We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
EzPickle used incorrectly on some environments
Some environments use `EzPickle` class incorrectly and thus the environment serialization does not result in an expected copy of the environment. An example of such class is the `HandReach-v0`: https://github.com/openai/gym/blob/a488c2fe2fbd4408ba9e193985ec2d86033cab6d/gym/envs/robotics/hand/reach.py#L66

I think the correct usage would be to move the call in the beginning of the `__init__`-method and call
```python
utils.EzPickle.__init__(
  distance_threshold=distance_threshold,
  n_substeps=n_substeps,
  relative_control=relative_control,
  initial_qpos=initial_qpos,
  reward_type=reward_type,
)
```
or alternatively
```python
utils.EzPickle.__init__(**locals())
```
Here's a simple script to verify the issue:
```python
import pickle

import gym


def main():
    env1 = gym.envs.make('HandReach-v0', distance_threshold=1e-6)
    env2 = pickle.loads(pickle.dumps(env1))

    assert env1.distance_threshold == env2.distance_threshold, (
        env1.distance_threshold, env2.distance_threshold)


if __name__ == '__main__':
    main()
```

Running it results in the following:
```
$ python ./tests/test_hand_copy.py
Traceback (most recent call last):
  File "./tests/test_hand_copy.py", line 15, in <module>
    main()
  File "./tests/test_hand_copy.py", line 11, in main
    env1.distance_threshold, env2.distance_threshold)
AssertionError: (1e-06, 0.01)
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `gym/envs/robotics/hand/reach.py`
Content:
```
1 import os
2 import numpy as np
3 
4 from gym import utils
5 from gym.envs.robotics import hand_env
6 from gym.envs.robotics.utils import robot_get_obs
7 
8 
9 FINGERTIP_SITE_NAMES = [
10     'robot0:S_fftip',
11     'robot0:S_mftip',
12     'robot0:S_rftip',
13     'robot0:S_lftip',
14     'robot0:S_thtip',
15 ]
16 
17 
18 DEFAULT_INITIAL_QPOS = {
19     'robot0:WRJ1': -0.16514339750464327,
20     'robot0:WRJ0': -0.31973286565062153,
21     'robot0:FFJ3': 0.14340512546557435,
22     'robot0:FFJ2': 0.32028208333591573,
23     'robot0:FFJ1': 0.7126053607727917,
24     'robot0:FFJ0': 0.6705281001412586,
25     'robot0:MFJ3': 0.000246444303701037,
26     'robot0:MFJ2': 0.3152655251085491,
27     'robot0:MFJ1': 0.7659800313729842,
28     'robot0:MFJ0': 0.7323156897425923,
29     'robot0:RFJ3': 0.00038520700007378114,
30     'robot0:RFJ2': 0.36743546201985233,
31     'robot0:RFJ1': 0.7119514095008576,
32     'robot0:RFJ0': 0.6699446327514138,
33     'robot0:LFJ4': 0.0525442258033891,
34     'robot0:LFJ3': -0.13615534724474673,
35     'robot0:LFJ2': 0.39872030433433003,
36     'robot0:LFJ1': 0.7415570009679252,
37     'robot0:LFJ0': 0.704096378652974,
38     'robot0:THJ4': 0.003673823825070126,
39     'robot0:THJ3': 0.5506291436028695,
40     'robot0:THJ2': -0.014515151997119306,
41     'robot0:THJ1': -0.0015229223564485414,
42     'robot0:THJ0': -0.7894883021600622,
43 }
44 
45 
46 # Ensure we get the path separator correct on windows
47 MODEL_XML_PATH = os.path.join('hand', 'reach.xml')
48 
49 
50 def goal_distance(goal_a, goal_b):
51     assert goal_a.shape == goal_b.shape
52     return np.linalg.norm(goal_a - goal_b, axis=-1)
53 
54 
55 class HandReachEnv(hand_env.HandEnv, utils.EzPickle):
56     def __init__(
57         self, distance_threshold=0.01, n_substeps=20, relative_control=False,
58         initial_qpos=DEFAULT_INITIAL_QPOS, reward_type='sparse',
59     ):
60         self.distance_threshold = distance_threshold
61         self.reward_type = reward_type
62 
63         hand_env.HandEnv.__init__(
64             self, MODEL_XML_PATH, n_substeps=n_substeps, initial_qpos=initial_qpos,
65             relative_control=relative_control)
66         utils.EzPickle.__init__(self)
67 
68     def _get_achieved_goal(self):
69         goal = [self.sim.data.get_site_xpos(name) for name in FINGERTIP_SITE_NAMES]
70         return np.array(goal).flatten()
71 
72     # GoalEnv methods
73     # ----------------------------
74 
75     def compute_reward(self, achieved_goal, goal, info):
76         d = goal_distance(achieved_goal, goal)
77         if self.reward_type == 'sparse':
78             return -(d > self.distance_threshold).astype(np.float32)
79         else:
80             return -d
81 
82     # RobotEnv methods
83     # ----------------------------
84 
85     def _env_setup(self, initial_qpos):
86         for name, value in initial_qpos.items():
87             self.sim.data.set_joint_qpos(name, value)
88         self.sim.forward()
89 
90         self.initial_goal = self._get_achieved_goal().copy()
91         self.palm_xpos = self.sim.data.body_xpos[self.sim.model.body_name2id('robot0:palm')].copy()
92 
93     def _get_obs(self):
94         robot_qpos, robot_qvel = robot_get_obs(self.sim)
95         achieved_goal = self._get_achieved_goal().ravel()
96         observation = np.concatenate([robot_qpos, robot_qvel, achieved_goal])
97         return {
98             'observation': observation.copy(),
99             'achieved_goal': achieved_goal.copy(),
100             'desired_goal': self.goal.copy(),
101         }
102 
103     def _sample_goal(self):
104         thumb_name = 'robot0:S_thtip'
105         finger_names = [name for name in FINGERTIP_SITE_NAMES if name != thumb_name]
106         finger_name = self.np_random.choice(finger_names)
107 
108         thumb_idx = FINGERTIP_SITE_NAMES.index(thumb_name)
109         finger_idx = FINGERTIP_SITE_NAMES.index(finger_name)
110         assert thumb_idx != finger_idx
111 
112         # Pick a meeting point above the hand.
113         meeting_pos = self.palm_xpos + np.array([0.0, -0.09, 0.05])
114         meeting_pos += self.np_random.normal(scale=0.005, size=meeting_pos.shape)
115 
116         # Slightly move meeting goal towards the respective finger to avoid that they
117         # overlap.
118         goal = self.initial_goal.copy().reshape(-1, 3)
119         for idx in [thumb_idx, finger_idx]:
120             offset_direction = (meeting_pos - goal[idx])
121             offset_direction /= np.linalg.norm(offset_direction)
122             goal[idx] = meeting_pos - 0.005 * offset_direction
123 
124         if self.np_random.uniform() < 0.1:
125             # With some probability, ask all fingers to move back to the origin.
126             # This avoids that the thumb constantly stays near the goal position already.
127             goal = self.initial_goal.copy()
128         return goal.flatten()
129 
130     def _is_success(self, achieved_goal, desired_goal):
131         d = goal_distance(achieved_goal, desired_goal)
132         return (d < self.distance_threshold).astype(np.float32)
133 
134     def _render_callback(self):
135         # Visualize targets.
136         sites_offset = (self.sim.data.site_xpos - self.sim.model.site_pos).copy()
137         goal = self.goal.reshape(5, 3)
138         for finger_idx in range(5):
139             site_name = 'target{}'.format(finger_idx)
140             site_id = self.sim.model.site_name2id(site_name)
141             self.sim.model.site_pos[site_id] = goal[finger_idx] - sites_offset[site_id]
142 
143         # Visualize finger positions.
144         achieved_goal = self._get_achieved_goal().reshape(5, 3)
145         for finger_idx in range(5):
146             site_name = 'finger{}'.format(finger_idx)
147             site_id = self.sim.model.site_name2id(site_name)
148             self.sim.model.site_pos[site_id] = achieved_goal[finger_idx] - sites_offset[site_id]
149         self.sim.forward()
150
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/gym/envs/robotics/hand/reach.py b/gym/envs/robotics/hand/reach.py
--- a/gym/envs/robotics/hand/reach.py
+++ b/gym/envs/robotics/hand/reach.py
@@ -57,13 +57,13 @@
         self, distance_threshold=0.01, n_substeps=20, relative_control=False,
         initial_qpos=DEFAULT_INITIAL_QPOS, reward_type='sparse',
     ):
+        utils.EzPickle.__init__(**locals())
         self.distance_threshold = distance_threshold
         self.reward_type = reward_type
 
         hand_env.HandEnv.__init__(
             self, MODEL_XML_PATH, n_substeps=n_substeps, initial_qpos=initial_qpos,
             relative_control=relative_control)
-        utils.EzPickle.__init__(self)
 
     def _get_achieved_goal(self):
         goal = [self.sim.data.get_site_xpos(name) for name in FINGERTIP_SITE_NAMES]

{"golden_diff": "diff --git a/gym/envs/robotics/hand/reach.py b/gym/envs/robotics/hand/reach.py\n--- a/gym/envs/robotics/hand/reach.py\n+++ b/gym/envs/robotics/hand/reach.py\n@@ -57,13 +57,13 @@\n         self, distance_threshold=0.01, n_substeps=20, relative_control=False,\n         initial_qpos=DEFAULT_INITIAL_QPOS, reward_type='sparse',\n     ):\n+        utils.EzPickle.__init__(**locals())\n         self.distance_threshold = distance_threshold\n         self.reward_type = reward_type\n \n         hand_env.HandEnv.__init__(\n             self, MODEL_XML_PATH, n_substeps=n_substeps, initial_qpos=initial_qpos,\n             relative_control=relative_control)\n-        utils.EzPickle.__init__(self)\n \n     def _get_achieved_goal(self):\n         goal = [self.sim.data.get_site_xpos(name) for name in FINGERTIP_SITE_NAMES]\n", "issue": "EzPickle used incorrectly on some environments\nSome environments use `EzPickle` class incorrectly and thus the environment serialization does not result in an expected copy of the environment. An example of such class is the `HandReach-v0`: https://github.com/openai/gym/blob/a488c2fe2fbd4408ba9e193985ec2d86033cab6d/gym/envs/robotics/hand/reach.py#L66\r\n\r\nI think the correct usage would be to move the call in the beginning of the `__init__`-method and call\r\n```python\r\nutils.EzPickle.__init__(\r\n  distance_threshold=distance_threshold,\r\n  n_substeps=n_substeps,\r\n  relative_control=relative_control,\r\n  initial_qpos=initial_qpos,\r\n  reward_type=reward_type,\r\n)\r\n```\r\nor alternatively\r\n```python\r\nutils.EzPickle.__init__(**locals())\r\n```\r\nHere's a simple script to verify the issue:\r\n```python\r\nimport pickle\r\n\r\nimport gym\r\n\r\n\r\ndef main():\r\n    env1 = gym.envs.make('HandReach-v0', distance_threshold=1e-6)\r\n    env2 = pickle.loads(pickle.dumps(env1))\r\n\r\n    assert env1.distance_threshold == env2.distance_threshold, (\r\n        env1.distance_threshold, env2.distance_threshold)\r\n\r\n\r\nif __name__ == '__main__':\r\n    main()\r\n```\r\n\r\nRunning it results in the following:\r\n```\r\n$ python ./tests/test_hand_copy.py\r\nTraceback (most recent call last):\r\n  File \"./tests/test_hand_copy.py\", line 15, in <module>\r\n    main()\r\n  File \"./tests/test_hand_copy.py\", line 11, in main\r\n    env1.distance_threshold, env2.distance_threshold)\r\nAssertionError: (1e-06, 0.01)\r\n```\r\n\n", "before_files": [{"content": "import os\nimport numpy as np\n\nfrom gym import utils\nfrom gym.envs.robotics import hand_env\nfrom gym.envs.robotics.utils import robot_get_obs\n\n\nFINGERTIP_SITE_NAMES = [\n    'robot0:S_fftip',\n    'robot0:S_mftip',\n    'robot0:S_rftip',\n    'robot0:S_lftip',\n    'robot0:S_thtip',\n]\n\n\nDEFAULT_INITIAL_QPOS = {\n    'robot0:WRJ1': -0.16514339750464327,\n    'robot0:WRJ0': -0.31973286565062153,\n    'robot0:FFJ3': 0.14340512546557435,\n    'robot0:FFJ2': 0.32028208333591573,\n    'robot0:FFJ1': 0.7126053607727917,\n    'robot0:FFJ0': 0.6705281001412586,\n    'robot0:MFJ3': 0.000246444303701037,\n    'robot0:MFJ2': 0.3152655251085491,\n    'robot0:MFJ1': 0.7659800313729842,\n    'robot0:MFJ0': 0.7323156897425923,\n    'robot0:RFJ3': 0.00038520700007378114,\n    'robot0:RFJ2': 0.36743546201985233,\n    'robot0:RFJ1': 0.7119514095008576,\n    'robot0:RFJ0': 0.6699446327514138,\n    'robot0:LFJ4': 0.0525442258033891,\n    'robot0:LFJ3': -0.13615534724474673,\n    'robot0:LFJ2': 0.39872030433433003,\n    'robot0:LFJ1': 0.7415570009679252,\n    'robot0:LFJ0': 0.704096378652974,\n    'robot0:THJ4': 0.003673823825070126,\n    'robot0:THJ3': 0.5506291436028695,\n    'robot0:THJ2': -0.014515151997119306,\n    'robot0:THJ1': -0.0015229223564485414,\n    'robot0:THJ0': -0.7894883021600622,\n}\n\n\n# Ensure we get the path separator correct on windows\nMODEL_XML_PATH = os.path.join('hand', 'reach.xml')\n\n\ndef goal_distance(goal_a, goal_b):\n    assert goal_a.shape == goal_b.shape\n    return np.linalg.norm(goal_a - goal_b, axis=-1)\n\n\nclass HandReachEnv(hand_env.HandEnv, utils.EzPickle):\n    def __init__(\n        self, distance_threshold=0.01, n_substeps=20, relative_control=False,\n        initial_qpos=DEFAULT_INITIAL_QPOS, reward_type='sparse',\n    ):\n        self.distance_threshold = distance_threshold\n        self.reward_type = reward_type\n\n        hand_env.HandEnv.__init__(\n            self, MODEL_XML_PATH, n_substeps=n_substeps, initial_qpos=initial_qpos,\n            relative_control=relative_control)\n        utils.EzPickle.__init__(self)\n\n    def _get_achieved_goal(self):\n        goal = [self.sim.data.get_site_xpos(name) for name in FINGERTIP_SITE_NAMES]\n        return np.array(goal).flatten()\n\n    # GoalEnv methods\n    # ----------------------------\n\n    def compute_reward(self, achieved_goal, goal, info):\n        d = goal_distance(achieved_goal, goal)\n        if self.reward_type == 'sparse':\n            return -(d > self.distance_threshold).astype(np.float32)\n        else:\n            return -d\n\n    # RobotEnv methods\n    # ----------------------------\n\n    def _env_setup(self, initial_qpos):\n        for name, value in initial_qpos.items():\n            self.sim.data.set_joint_qpos(name, value)\n        self.sim.forward()\n\n        self.initial_goal = self._get_achieved_goal().copy()\n        self.palm_xpos = self.sim.data.body_xpos[self.sim.model.body_name2id('robot0:palm')].copy()\n\n    def _get_obs(self):\n        robot_qpos, robot_qvel = robot_get_obs(self.sim)\n        achieved_goal = self._get_achieved_goal().ravel()\n        observation = np.concatenate([robot_qpos, robot_qvel, achieved_goal])\n        return {\n            'observation': observation.copy(),\n            'achieved_goal': achieved_goal.copy(),\n            'desired_goal': self.goal.copy(),\n        }\n\n    def _sample_goal(self):\n        thumb_name = 'robot0:S_thtip'\n        finger_names = [name for name in FINGERTIP_SITE_NAMES if name != thumb_name]\n        finger_name = self.np_random.choice(finger_names)\n\n        thumb_idx = FINGERTIP_SITE_NAMES.index(thumb_name)\n        finger_idx = FINGERTIP_SITE_NAMES.index(finger_name)\n        assert thumb_idx != finger_idx\n\n        # Pick a meeting point above the hand.\n        meeting_pos = self.palm_xpos + np.array([0.0, -0.09, 0.05])\n        meeting_pos += self.np_random.normal(scale=0.005, size=meeting_pos.shape)\n\n        # Slightly move meeting goal towards the respective finger to avoid that they\n        # overlap.\n        goal = self.initial_goal.copy().reshape(-1, 3)\n        for idx in [thumb_idx, finger_idx]:\n            offset_direction = (meeting_pos - goal[idx])\n            offset_direction /= np.linalg.norm(offset_direction)\n            goal[idx] = meeting_pos - 0.005 * offset_direction\n\n        if self.np_random.uniform() < 0.1:\n            # With some probability, ask all fingers to move back to the origin.\n            # This avoids that the thumb constantly stays near the goal position already.\n            goal = self.initial_goal.copy()\n        return goal.flatten()\n\n    def _is_success(self, achieved_goal, desired_goal):\n        d = goal_distance(achieved_goal, desired_goal)\n        return (d < self.distance_threshold).astype(np.float32)\n\n    def _render_callback(self):\n        # Visualize targets.\n        sites_offset = (self.sim.data.site_xpos - self.sim.model.site_pos).copy()\n        goal = self.goal.reshape(5, 3)\n        for finger_idx in range(5):\n            site_name = 'target{}'.format(finger_idx)\n            site_id = self.sim.model.site_name2id(site_name)\n            self.sim.model.site_pos[site_id] = goal[finger_idx] - sites_offset[site_id]\n\n        # Visualize finger positions.\n        achieved_goal = self._get_achieved_goal().reshape(5, 3)\n        for finger_idx in range(5):\n            site_name = 'finger{}'.format(finger_idx)\n            site_id = self.sim.model.site_name2id(site_name)\n            self.sim.model.site_pos[site_id] = achieved_goal[finger_idx] - sites_offset[site_id]\n        self.sim.forward()\n", "path": "gym/envs/robotics/hand/reach.py"}], "after_files": [{"content": "import os\nimport numpy as np\n\nfrom gym import utils\nfrom gym.envs.robotics import hand_env\nfrom gym.envs.robotics.utils import robot_get_obs\n\n\nFINGERTIP_SITE_NAMES = [\n    'robot0:S_fftip',\n    'robot0:S_mftip',\n    'robot0:S_rftip',\n    'robot0:S_lftip',\n    'robot0:S_thtip',\n]\n\n\nDEFAULT_INITIAL_QPOS = {\n    'robot0:WRJ1': -0.16514339750464327,\n    'robot0:WRJ0': -0.31973286565062153,\n    'robot0:FFJ3': 0.14340512546557435,\n    'robot0:FFJ2': 0.32028208333591573,\n    'robot0:FFJ1': 0.7126053607727917,\n    'robot0:FFJ0': 0.6705281001412586,\n    'robot0:MFJ3': 0.000246444303701037,\n    'robot0:MFJ2': 0.3152655251085491,\n    'robot0:MFJ1': 0.7659800313729842,\n    'robot0:MFJ0': 0.7323156897425923,\n    'robot0:RFJ3': 0.00038520700007378114,\n    'robot0:RFJ2': 0.36743546201985233,\n    'robot0:RFJ1': 0.7119514095008576,\n    'robot0:RFJ0': 0.6699446327514138,\n    'robot0:LFJ4': 0.0525442258033891,\n    'robot0:LFJ3': -0.13615534724474673,\n    'robot0:LFJ2': 0.39872030433433003,\n    'robot0:LFJ1': 0.7415570009679252,\n    'robot0:LFJ0': 0.704096378652974,\n    'robot0:THJ4': 0.003673823825070126,\n    'robot0:THJ3': 0.5506291436028695,\n    'robot0:THJ2': -0.014515151997119306,\n    'robot0:THJ1': -0.0015229223564485414,\n    'robot0:THJ0': -0.7894883021600622,\n}\n\n\n# Ensure we get the path separator correct on windows\nMODEL_XML_PATH = os.path.join('hand', 'reach.xml')\n\n\ndef goal_distance(goal_a, goal_b):\n    assert goal_a.shape == goal_b.shape\n    return np.linalg.norm(goal_a - goal_b, axis=-1)\n\n\nclass HandReachEnv(hand_env.HandEnv, utils.EzPickle):\n    def __init__(\n        self, distance_threshold=0.01, n_substeps=20, relative_control=False,\n        initial_qpos=DEFAULT_INITIAL_QPOS, reward_type='sparse',\n    ):\n        utils.EzPickle.__init__(**locals())\n        self.distance_threshold = distance_threshold\n        self.reward_type = reward_type\n\n        hand_env.HandEnv.__init__(\n            self, MODEL_XML_PATH, n_substeps=n_substeps, initial_qpos=initial_qpos,\n            relative_control=relative_control)\n\n    def _get_achieved_goal(self):\n        goal = [self.sim.data.get_site_xpos(name) for name in FINGERTIP_SITE_NAMES]\n        return np.array(goal).flatten()\n\n    # GoalEnv methods\n    # ----------------------------\n\n    def compute_reward(self, achieved_goal, goal, info):\n        d = goal_distance(achieved_goal, goal)\n        if self.reward_type == 'sparse':\n            return -(d > self.distance_threshold).astype(np.float32)\n        else:\n            return -d\n\n    # RobotEnv methods\n    # ----------------------------\n\n    def _env_setup(self, initial_qpos):\n        for name, value in initial_qpos.items():\n            self.sim.data.set_joint_qpos(name, value)\n        self.sim.forward()\n\n        self.initial_goal = self._get_achieved_goal().copy()\n        self.palm_xpos = self.sim.data.body_xpos[self.sim.model.body_name2id('robot0:palm')].copy()\n\n    def _get_obs(self):\n        robot_qpos, robot_qvel = robot_get_obs(self.sim)\n        achieved_goal = self._get_achieved_goal().ravel()\n        observation = np.concatenate([robot_qpos, robot_qvel, achieved_goal])\n        return {\n            'observation': observation.copy(),\n            'achieved_goal': achieved_goal.copy(),\n            'desired_goal': self.goal.copy(),\n        }\n\n    def _sample_goal(self):\n        thumb_name = 'robot0:S_thtip'\n        finger_names = [name for name in FINGERTIP_SITE_NAMES if name != thumb_name]\n        finger_name = self.np_random.choice(finger_names)\n\n        thumb_idx = FINGERTIP_SITE_NAMES.index(thumb_name)\n        finger_idx = FINGERTIP_SITE_NAMES.index(finger_name)\n        assert thumb_idx != finger_idx\n\n        # Pick a meeting point above the hand.\n        meeting_pos = self.palm_xpos + np.array([0.0, -0.09, 0.05])\n        meeting_pos += self.np_random.normal(scale=0.005, size=meeting_pos.shape)\n\n        # Slightly move meeting goal towards the respective finger to avoid that they\n        # overlap.\n        goal = self.initial_goal.copy().reshape(-1, 3)\n        for idx in [thumb_idx, finger_idx]:\n            offset_direction = (meeting_pos - goal[idx])\n            offset_direction /= np.linalg.norm(offset_direction)\n            goal[idx] = meeting_pos - 0.005 * offset_direction\n\n        if self.np_random.uniform() < 0.1:\n            # With some probability, ask all fingers to move back to the origin.\n            # This avoids that the thumb constantly stays near the goal position already.\n            goal = self.initial_goal.copy()\n        return goal.flatten()\n\n    def _is_success(self, achieved_goal, desired_goal):\n        d = goal_distance(achieved_goal, desired_goal)\n        return (d < self.distance_threshold).astype(np.float32)\n\n    def _render_callback(self):\n        # Visualize targets.\n        sites_offset = (self.sim.data.site_xpos - self.sim.model.site_pos).copy()\n        goal = self.goal.reshape(5, 3)\n        for finger_idx in range(5):\n            site_name = 'target{}'.format(finger_idx)\n            site_id = self.sim.model.site_name2id(site_name)\n            self.sim.model.site_pos[site_id] = goal[finger_idx] - sites_offset[site_id]\n\n        # Visualize finger positions.\n        achieved_goal = self._get_achieved_goal().reshape(5, 3)\n        for finger_idx in range(5):\n            site_name = 'finger{}'.format(finger_idx)\n            site_id = self.sim.model.site_name2id(site_name)\n            self.sim.model.site_pos[site_id] = achieved_goal[finger_idx] - sites_offset[site_id]\n        self.sim.forward()\n", "path": "gym/envs/robotics/hand/reach.py"}]}