We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Shape of env_info of HalfCheetah* environments not compatible with TrajectoryBatch
A trajectory of `HalfCheetahVel` and `HalfCheetahDir` should have an `env_info` dict of numpy array but they do not. The `task` in their `env_info` is instead a dict. 

`env_info` is assumed by `TrajectoryBatch` to be a dict of numpy array. 

This is a bug that will break an algorithm when it uses `HalfCheetah` together with `TrajectoryBatch`.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/garage/envs/mujoco/half_cheetah_vel_env.py`
Content:
```
1 """Variant of the HalfCheetahEnv with different target velocity."""
2 import numpy as np
3 
4 from garage.envs.mujoco.half_cheetah_env_meta_base import (
5     HalfCheetahEnvMetaBase)  # noqa: E501
6 
7 
8 class HalfCheetahVelEnv(HalfCheetahEnvMetaBase):
9     """Half-cheetah environment with target velocity, as described in [1].
10 
11     The code is adapted from
12     https://github.com/cbfinn/maml_rl/blob/9c8e2ebd741cb0c7b8bf2d040c4caeeb8e06cc95/rllab/envs/mujoco/half_cheetah_env_rand.py
13 
14     The half-cheetah follows the dynamics from MuJoCo [2], and receives at each
15     time step a reward composed of a control cost and a penalty equal to the
16     difference between its current velocity and the target velocity. The tasks
17     are generated by sampling the target velocities from the uniform
18     distribution on [0, 2].
19 
20     [1] Chelsea Finn, Pieter Abbeel, Sergey Levine, "Model-Agnostic
21         Meta-Learning for Fast Adaptation of Deep Networks", 2017
22         (https://arxiv.org/abs/1703.03400)
23     [2] Emanuel Todorov, Tom Erez, Yuval Tassa, "MuJoCo: A physics engine for
24         model-based control", 2012
25         (https://homes.cs.washington.edu/~todorov/papers/TodorovIROS12.pdf)
26 
27     Args:
28         task (dict or None):
29             velocity (float): Target velocity, usually between 0 and 2.
30 
31     """
32 
33     def __init__(self, task=None):
34         super().__init__(task or {'velocity': 0.})
35 
36     def step(self, action):
37         """Take one step in the environment.
38 
39         Equivalent to step in HalfCheetahEnv, but with different rewards.
40 
41         Args:
42             action (np.ndarray): The action to take in the environment.
43 
44         Returns:
45             tuple:
46                 * observation (np.ndarray): The observation of the environment.
47                 * reward (float): The reward acquired at this time step.
48                 * done (boolean): Whether the environment was completed at this
49                     time step. Always False for this environment.
50                 * infos (dict):
51                     * reward_forward (float): Reward for moving, ignoring the
52                         control cost.
53                     * reward_ctrl (float): The reward for acting i.e. the
54                         control cost (always negative).
55                     * task_vel (float): Target velocity.
56                         Usually between 0 and 2.
57 
58         """
59         xposbefore = self.sim.data.qpos[0]
60         self.do_simulation(action, self.frame_skip)
61         xposafter = self.sim.data.qpos[0]
62 
63         forward_vel = (xposafter - xposbefore) / self.dt
64         forward_reward = -1.0 * abs(forward_vel - self._task['velocity'])
65         ctrl_cost = 0.5 * 1e-1 * np.sum(np.square(action))
66 
67         observation = self._get_obs()
68         reward = forward_reward - ctrl_cost
69         done = False
70         infos = dict(reward_forward=forward_reward,
71                      reward_ctrl=-ctrl_cost,
72                      task_vel=self._task['velocity'])
73         return observation, reward, done, infos
74 
75     def sample_tasks(self, num_tasks):
76         """Sample a list of `num_tasks` tasks.
77 
78         Args:
79             num_tasks (int): Number of tasks to sample.
80 
81         Returns:
82             list[dict[str, float]]: A list of "tasks," where each task is a
83                 dictionary containing a single key, "velocity", mapping to a
84                 value between 0 and 2.
85 
86         """
87         velocities = self.np_random.uniform(0.0, 2.0, size=(num_tasks, ))
88         tasks = [{'velocity': velocity} for velocity in velocities]
89         return tasks
90 
91     def set_task(self, task):
92         """Reset with a task.
93 
94         Args:
95             task (dict[str, float]): A task (a dictionary containing a single
96                 key, "velocity", usually between 0 and 2).
97 
98         """
99         self._task = task
100
```

Path: `src/garage/envs/mujoco/half_cheetah_dir_env.py`
Content:
```
1 """Variant of the HalfCheetahEnv with different target directions."""
2 import numpy as np
3 
4 from garage.envs.mujoco.half_cheetah_env_meta_base import (
5     HalfCheetahEnvMetaBase)  # noqa: E501
6 
7 
8 class HalfCheetahDirEnv(HalfCheetahEnvMetaBase):
9     """Half-cheetah environment with target direction, as described in [1].
10 
11     The code is adapted from
12     https://github.com/cbfinn/maml_rl/blob/9c8e2ebd741cb0c7b8bf2d040c4caeeb8e06cc95/rllab/envs/mujoco/half_cheetah_env_rand_direc.py
13 
14     The half-cheetah follows the dynamics from MuJoCo [2], and receives at each
15     time step a reward composed of a control cost and a reward equal to its
16     velocity in the target direction. The tasks are generated by sampling the
17     target directions from a Bernoulli distribution on {-1, 1} with parameter
18     0.5 (-1: backward, +1: forward).
19 
20     [1] Chelsea Finn, Pieter Abbeel, Sergey Levine, "Model-Agnostic
21         Meta-Learning for Fast Adaptation of Deep Networks", 2017
22         (https://arxiv.org/abs/1703.03400)
23     [2] Emanuel Todorov, Tom Erez, Yuval Tassa, "MuJoCo: A physics engine for
24         model-based control", 2012
25         (https://homes.cs.washington.edu/~todorov/papers/TodorovIROS12.pdf)
26 
27     Args:
28         task (dict or None):
29             direction (float): Target direction, either -1 or 1.
30 
31     """
32 
33     def __init__(self, task=None):
34         super().__init__(task or {'direction': 1.})
35 
36     def step(self, action):
37         """Take one step in the environment.
38 
39         Equivalent to step in HalfCheetahEnv, but with different rewards.
40 
41         Args:
42             action (np.ndarray): The action to take in the environment.
43 
44         Raises:
45             ValueError: If the current direction is not 1.0 or -1.0.
46 
47         Returns:
48             tuple:
49                 * observation (np.ndarray): The observation of the environment.
50                 * reward (float): The reward acquired at this time step.
51                 * done (boolean): Whether the environment was completed at this
52                     time step. Always False for this environment.
53                 * infos (dict):
54                     * reward_forward (float): Reward for moving, ignoring the
55                         control cost.
56                     * reward_ctrl (float): The reward for acting i.e. the
57                         control cost (always negative).
58                     * task_dir (float): Target direction. 1.0 for forwards,
59                         -1.0 for backwards.
60 
61         """
62         xposbefore = self.sim.data.qpos[0]
63         self.do_simulation(action, self.frame_skip)
64         xposafter = self.sim.data.qpos[0]
65 
66         forward_vel = (xposafter - xposbefore) / self.dt
67         forward_reward = self._task['direction'] * forward_vel
68         ctrl_cost = 0.5 * 1e-1 * np.sum(np.square(action))
69 
70         observation = self._get_obs()
71         reward = forward_reward - ctrl_cost
72         done = False
73         if self._task['direction'] == 1.:
74             task_name = 'fowrad'
75         elif self._task['direction'] == -1.:
76             task_name = 'backward'
77         else:
78             raise ValueError('task direction should be 1. or -1.')
79         infos = dict(reward_forward=forward_reward,
80                      reward_ctrl=-ctrl_cost,
81                      task_dir=self._task['direction'],
82                      task_name=task_name)
83         return observation, reward, done, infos
84 
85     def sample_tasks(self, num_tasks):
86         """Sample a list of `num_tasks` tasks.
87 
88         Args:
89             num_tasks (int): Number of tasks to sample.
90 
91         Returns:
92             list[dict[str, float]]: A list of "tasks," where each task is a
93                 dictionary containing a single key, "direction", mapping to -1
94                 or 1.
95 
96         """
97         directions = (
98             2 * self.np_random.binomial(1, p=0.5, size=(num_tasks, )) - 1)
99         tasks = [{'direction': direction} for direction in directions]
100         return tasks
101 
102     def set_task(self, task):
103         """Reset with a task.
104 
105         Args:
106             task (dict[str, float]): A task (a dictionary containing a single
107                 key, "direction", mapping to -1 or 1).
108 
109         """
110         self._task = task
111
```
--- 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/src/garage/envs/mujoco/half_cheetah_dir_env.py b/src/garage/envs/mujoco/half_cheetah_dir_env.py
--- a/src/garage/envs/mujoco/half_cheetah_dir_env.py
+++ b/src/garage/envs/mujoco/half_cheetah_dir_env.py
@@ -76,9 +76,9 @@
             task_name = 'backward'
         else:
             raise ValueError('task direction should be 1. or -1.')
-        infos = dict(reward_forward=forward_reward,
-                     reward_ctrl=-ctrl_cost,
-                     task_dir=self._task['direction'],
+        infos = dict(reward_forward=np.asarray([forward_reward]),
+                     reward_ctrl=np.asarray([-ctrl_cost]),
+                     task_dir=np.asarray([self._task['direction']]),
                      task_name=task_name)
         return observation, reward, done, infos
 
diff --git a/src/garage/envs/mujoco/half_cheetah_vel_env.py b/src/garage/envs/mujoco/half_cheetah_vel_env.py
--- a/src/garage/envs/mujoco/half_cheetah_vel_env.py
+++ b/src/garage/envs/mujoco/half_cheetah_vel_env.py
@@ -67,9 +67,9 @@
         observation = self._get_obs()
         reward = forward_reward - ctrl_cost
         done = False
-        infos = dict(reward_forward=forward_reward,
-                     reward_ctrl=-ctrl_cost,
-                     task_vel=self._task['velocity'])
+        infos = dict(reward_forward=np.asarray([forward_reward]),
+                     reward_ctrl=np.asarray([-ctrl_cost]),
+                     task_vel=np.asarray([self._task['velocity']]))
         return observation, reward, done, infos
 
     def sample_tasks(self, num_tasks):

{"golden_diff": "diff --git a/src/garage/envs/mujoco/half_cheetah_dir_env.py b/src/garage/envs/mujoco/half_cheetah_dir_env.py\n--- a/src/garage/envs/mujoco/half_cheetah_dir_env.py\n+++ b/src/garage/envs/mujoco/half_cheetah_dir_env.py\n@@ -76,9 +76,9 @@\n             task_name = 'backward'\n         else:\n             raise ValueError('task direction should be 1. or -1.')\n-        infos = dict(reward_forward=forward_reward,\n-                     reward_ctrl=-ctrl_cost,\n-                     task_dir=self._task['direction'],\n+        infos = dict(reward_forward=np.asarray([forward_reward]),\n+                     reward_ctrl=np.asarray([-ctrl_cost]),\n+                     task_dir=np.asarray([self._task['direction']]),\n                      task_name=task_name)\n         return observation, reward, done, infos\n \ndiff --git a/src/garage/envs/mujoco/half_cheetah_vel_env.py b/src/garage/envs/mujoco/half_cheetah_vel_env.py\n--- a/src/garage/envs/mujoco/half_cheetah_vel_env.py\n+++ b/src/garage/envs/mujoco/half_cheetah_vel_env.py\n@@ -67,9 +67,9 @@\n         observation = self._get_obs()\n         reward = forward_reward - ctrl_cost\n         done = False\n-        infos = dict(reward_forward=forward_reward,\n-                     reward_ctrl=-ctrl_cost,\n-                     task_vel=self._task['velocity'])\n+        infos = dict(reward_forward=np.asarray([forward_reward]),\n+                     reward_ctrl=np.asarray([-ctrl_cost]),\n+                     task_vel=np.asarray([self._task['velocity']]))\n         return observation, reward, done, infos\n \n     def sample_tasks(self, num_tasks):\n", "issue": "Shape of env_info of HalfCheetah* environments not compatible with TrajectoryBatch\nA trajectory of `HalfCheetahVel` and `HalfCheetahDir` should have an `env_info` dict of numpy array but they do not. The `task` in their `env_info` is instead a dict. \r\n\r\n`env_info` is assumed by `TrajectoryBatch` to be a dict of numpy array. \r\n\r\nThis is a bug that will break an algorithm when it uses `HalfCheetah` together with `TrajectoryBatch`.\n", "before_files": [{"content": "\"\"\"Variant of the HalfCheetahEnv with different target velocity.\"\"\"\nimport numpy as np\n\nfrom garage.envs.mujoco.half_cheetah_env_meta_base import (\n    HalfCheetahEnvMetaBase)  # noqa: E501\n\n\nclass HalfCheetahVelEnv(HalfCheetahEnvMetaBase):\n    \"\"\"Half-cheetah environment with target velocity, as described in [1].\n\n    The code is adapted from\n    https://github.com/cbfinn/maml_rl/blob/9c8e2ebd741cb0c7b8bf2d040c4caeeb8e06cc95/rllab/envs/mujoco/half_cheetah_env_rand.py\n\n    The half-cheetah follows the dynamics from MuJoCo [2], and receives at each\n    time step a reward composed of a control cost and a penalty equal to the\n    difference between its current velocity and the target velocity. The tasks\n    are generated by sampling the target velocities from the uniform\n    distribution on [0, 2].\n\n    [1] Chelsea Finn, Pieter Abbeel, Sergey Levine, \"Model-Agnostic\n        Meta-Learning for Fast Adaptation of Deep Networks\", 2017\n        (https://arxiv.org/abs/1703.03400)\n    [2] Emanuel Todorov, Tom Erez, Yuval Tassa, \"MuJoCo: A physics engine for\n        model-based control\", 2012\n        (https://homes.cs.washington.edu/~todorov/papers/TodorovIROS12.pdf)\n\n    Args:\n        task (dict or None):\n            velocity (float): Target velocity, usually between 0 and 2.\n\n    \"\"\"\n\n    def __init__(self, task=None):\n        super().__init__(task or {'velocity': 0.})\n\n    def step(self, action):\n        \"\"\"Take one step in the environment.\n\n        Equivalent to step in HalfCheetahEnv, but with different rewards.\n\n        Args:\n            action (np.ndarray): The action to take in the environment.\n\n        Returns:\n            tuple:\n                * observation (np.ndarray): The observation of the environment.\n                * reward (float): The reward acquired at this time step.\n                * done (boolean): Whether the environment was completed at this\n                    time step. Always False for this environment.\n                * infos (dict):\n                    * reward_forward (float): Reward for moving, ignoring the\n                        control cost.\n                    * reward_ctrl (float): The reward for acting i.e. the\n                        control cost (always negative).\n                    * task_vel (float): Target velocity.\n                        Usually between 0 and 2.\n\n        \"\"\"\n        xposbefore = self.sim.data.qpos[0]\n        self.do_simulation(action, self.frame_skip)\n        xposafter = self.sim.data.qpos[0]\n\n        forward_vel = (xposafter - xposbefore) / self.dt\n        forward_reward = -1.0 * abs(forward_vel - self._task['velocity'])\n        ctrl_cost = 0.5 * 1e-1 * np.sum(np.square(action))\n\n        observation = self._get_obs()\n        reward = forward_reward - ctrl_cost\n        done = False\n        infos = dict(reward_forward=forward_reward,\n                     reward_ctrl=-ctrl_cost,\n                     task_vel=self._task['velocity'])\n        return observation, reward, done, infos\n\n    def sample_tasks(self, num_tasks):\n        \"\"\"Sample a list of `num_tasks` tasks.\n\n        Args:\n            num_tasks (int): Number of tasks to sample.\n\n        Returns:\n            list[dict[str, float]]: A list of \"tasks,\" where each task is a\n                dictionary containing a single key, \"velocity\", mapping to a\n                value between 0 and 2.\n\n        \"\"\"\n        velocities = self.np_random.uniform(0.0, 2.0, size=(num_tasks, ))\n        tasks = [{'velocity': velocity} for velocity in velocities]\n        return tasks\n\n    def set_task(self, task):\n        \"\"\"Reset with a task.\n\n        Args:\n            task (dict[str, float]): A task (a dictionary containing a single\n                key, \"velocity\", usually between 0 and 2).\n\n        \"\"\"\n        self._task = task\n", "path": "src/garage/envs/mujoco/half_cheetah_vel_env.py"}, {"content": "\"\"\"Variant of the HalfCheetahEnv with different target directions.\"\"\"\nimport numpy as np\n\nfrom garage.envs.mujoco.half_cheetah_env_meta_base import (\n    HalfCheetahEnvMetaBase)  # noqa: E501\n\n\nclass HalfCheetahDirEnv(HalfCheetahEnvMetaBase):\n    \"\"\"Half-cheetah environment with target direction, as described in [1].\n\n    The code is adapted from\n    https://github.com/cbfinn/maml_rl/blob/9c8e2ebd741cb0c7b8bf2d040c4caeeb8e06cc95/rllab/envs/mujoco/half_cheetah_env_rand_direc.py\n\n    The half-cheetah follows the dynamics from MuJoCo [2], and receives at each\n    time step a reward composed of a control cost and a reward equal to its\n    velocity in the target direction. The tasks are generated by sampling the\n    target directions from a Bernoulli distribution on {-1, 1} with parameter\n    0.5 (-1: backward, +1: forward).\n\n    [1] Chelsea Finn, Pieter Abbeel, Sergey Levine, \"Model-Agnostic\n        Meta-Learning for Fast Adaptation of Deep Networks\", 2017\n        (https://arxiv.org/abs/1703.03400)\n    [2] Emanuel Todorov, Tom Erez, Yuval Tassa, \"MuJoCo: A physics engine for\n        model-based control\", 2012\n        (https://homes.cs.washington.edu/~todorov/papers/TodorovIROS12.pdf)\n\n    Args:\n        task (dict or None):\n            direction (float): Target direction, either -1 or 1.\n\n    \"\"\"\n\n    def __init__(self, task=None):\n        super().__init__(task or {'direction': 1.})\n\n    def step(self, action):\n        \"\"\"Take one step in the environment.\n\n        Equivalent to step in HalfCheetahEnv, but with different rewards.\n\n        Args:\n            action (np.ndarray): The action to take in the environment.\n\n        Raises:\n            ValueError: If the current direction is not 1.0 or -1.0.\n\n        Returns:\n            tuple:\n                * observation (np.ndarray): The observation of the environment.\n                * reward (float): The reward acquired at this time step.\n                * done (boolean): Whether the environment was completed at this\n                    time step. Always False for this environment.\n                * infos (dict):\n                    * reward_forward (float): Reward for moving, ignoring the\n                        control cost.\n                    * reward_ctrl (float): The reward for acting i.e. the\n                        control cost (always negative).\n                    * task_dir (float): Target direction. 1.0 for forwards,\n                        -1.0 for backwards.\n\n        \"\"\"\n        xposbefore = self.sim.data.qpos[0]\n        self.do_simulation(action, self.frame_skip)\n        xposafter = self.sim.data.qpos[0]\n\n        forward_vel = (xposafter - xposbefore) / self.dt\n        forward_reward = self._task['direction'] * forward_vel\n        ctrl_cost = 0.5 * 1e-1 * np.sum(np.square(action))\n\n        observation = self._get_obs()\n        reward = forward_reward - ctrl_cost\n        done = False\n        if self._task['direction'] == 1.:\n            task_name = 'fowrad'\n        elif self._task['direction'] == -1.:\n            task_name = 'backward'\n        else:\n            raise ValueError('task direction should be 1. or -1.')\n        infos = dict(reward_forward=forward_reward,\n                     reward_ctrl=-ctrl_cost,\n                     task_dir=self._task['direction'],\n                     task_name=task_name)\n        return observation, reward, done, infos\n\n    def sample_tasks(self, num_tasks):\n        \"\"\"Sample a list of `num_tasks` tasks.\n\n        Args:\n            num_tasks (int): Number of tasks to sample.\n\n        Returns:\n            list[dict[str, float]]: A list of \"tasks,\" where each task is a\n                dictionary containing a single key, \"direction\", mapping to -1\n                or 1.\n\n        \"\"\"\n        directions = (\n            2 * self.np_random.binomial(1, p=0.5, size=(num_tasks, )) - 1)\n        tasks = [{'direction': direction} for direction in directions]\n        return tasks\n\n    def set_task(self, task):\n        \"\"\"Reset with a task.\n\n        Args:\n            task (dict[str, float]): A task (a dictionary containing a single\n                key, \"direction\", mapping to -1 or 1).\n\n        \"\"\"\n        self._task = task\n", "path": "src/garage/envs/mujoco/half_cheetah_dir_env.py"}], "after_files": [{"content": "\"\"\"Variant of the HalfCheetahEnv with different target velocity.\"\"\"\nimport numpy as np\n\nfrom garage.envs.mujoco.half_cheetah_env_meta_base import (\n    HalfCheetahEnvMetaBase)  # noqa: E501\n\n\nclass HalfCheetahVelEnv(HalfCheetahEnvMetaBase):\n    \"\"\"Half-cheetah environment with target velocity, as described in [1].\n\n    The code is adapted from\n    https://github.com/cbfinn/maml_rl/blob/9c8e2ebd741cb0c7b8bf2d040c4caeeb8e06cc95/rllab/envs/mujoco/half_cheetah_env_rand.py\n\n    The half-cheetah follows the dynamics from MuJoCo [2], and receives at each\n    time step a reward composed of a control cost and a penalty equal to the\n    difference between its current velocity and the target velocity. The tasks\n    are generated by sampling the target velocities from the uniform\n    distribution on [0, 2].\n\n    [1] Chelsea Finn, Pieter Abbeel, Sergey Levine, \"Model-Agnostic\n        Meta-Learning for Fast Adaptation of Deep Networks\", 2017\n        (https://arxiv.org/abs/1703.03400)\n    [2] Emanuel Todorov, Tom Erez, Yuval Tassa, \"MuJoCo: A physics engine for\n        model-based control\", 2012\n        (https://homes.cs.washington.edu/~todorov/papers/TodorovIROS12.pdf)\n\n    Args:\n        task (dict or None):\n            velocity (float): Target velocity, usually between 0 and 2.\n\n    \"\"\"\n\n    def __init__(self, task=None):\n        super().__init__(task or {'velocity': 0.})\n\n    def step(self, action):\n        \"\"\"Take one step in the environment.\n\n        Equivalent to step in HalfCheetahEnv, but with different rewards.\n\n        Args:\n            action (np.ndarray): The action to take in the environment.\n\n        Returns:\n            tuple:\n                * observation (np.ndarray): The observation of the environment.\n                * reward (float): The reward acquired at this time step.\n                * done (boolean): Whether the environment was completed at this\n                    time step. Always False for this environment.\n                * infos (dict):\n                    * reward_forward (float): Reward for moving, ignoring the\n                        control cost.\n                    * reward_ctrl (float): The reward for acting i.e. the\n                        control cost (always negative).\n                    * task_vel (float): Target velocity.\n                        Usually between 0 and 2.\n\n        \"\"\"\n        xposbefore = self.sim.data.qpos[0]\n        self.do_simulation(action, self.frame_skip)\n        xposafter = self.sim.data.qpos[0]\n\n        forward_vel = (xposafter - xposbefore) / self.dt\n        forward_reward = -1.0 * abs(forward_vel - self._task['velocity'])\n        ctrl_cost = 0.5 * 1e-1 * np.sum(np.square(action))\n\n        observation = self._get_obs()\n        reward = forward_reward - ctrl_cost\n        done = False\n        infos = dict(reward_forward=np.asarray([forward_reward]),\n                     reward_ctrl=np.asarray([-ctrl_cost]),\n                     task_vel=np.asarray([self._task['velocity']]))\n        return observation, reward, done, infos\n\n    def sample_tasks(self, num_tasks):\n        \"\"\"Sample a list of `num_tasks` tasks.\n\n        Args:\n            num_tasks (int): Number of tasks to sample.\n\n        Returns:\n            list[dict[str, float]]: A list of \"tasks,\" where each task is a\n                dictionary containing a single key, \"velocity\", mapping to a\n                value between 0 and 2.\n\n        \"\"\"\n        velocities = self.np_random.uniform(0.0, 2.0, size=(num_tasks, ))\n        tasks = [{'velocity': velocity} for velocity in velocities]\n        return tasks\n\n    def set_task(self, task):\n        \"\"\"Reset with a task.\n\n        Args:\n            task (dict[str, float]): A task (a dictionary containing a single\n                key, \"velocity\", usually between 0 and 2).\n\n        \"\"\"\n        self._task = task\n", "path": "src/garage/envs/mujoco/half_cheetah_vel_env.py"}, {"content": "\"\"\"Variant of the HalfCheetahEnv with different target directions.\"\"\"\nimport numpy as np\n\nfrom garage.envs.mujoco.half_cheetah_env_meta_base import (\n    HalfCheetahEnvMetaBase)  # noqa: E501\n\n\nclass HalfCheetahDirEnv(HalfCheetahEnvMetaBase):\n    \"\"\"Half-cheetah environment with target direction, as described in [1].\n\n    The code is adapted from\n    https://github.com/cbfinn/maml_rl/blob/9c8e2ebd741cb0c7b8bf2d040c4caeeb8e06cc95/rllab/envs/mujoco/half_cheetah_env_rand_direc.py\n\n    The half-cheetah follows the dynamics from MuJoCo [2], and receives at each\n    time step a reward composed of a control cost and a reward equal to its\n    velocity in the target direction. The tasks are generated by sampling the\n    target directions from a Bernoulli distribution on {-1, 1} with parameter\n    0.5 (-1: backward, +1: forward).\n\n    [1] Chelsea Finn, Pieter Abbeel, Sergey Levine, \"Model-Agnostic\n        Meta-Learning for Fast Adaptation of Deep Networks\", 2017\n        (https://arxiv.org/abs/1703.03400)\n    [2] Emanuel Todorov, Tom Erez, Yuval Tassa, \"MuJoCo: A physics engine for\n        model-based control\", 2012\n        (https://homes.cs.washington.edu/~todorov/papers/TodorovIROS12.pdf)\n\n    Args:\n        task (dict or None):\n            direction (float): Target direction, either -1 or 1.\n\n    \"\"\"\n\n    def __init__(self, task=None):\n        super().__init__(task or {'direction': 1.})\n\n    def step(self, action):\n        \"\"\"Take one step in the environment.\n\n        Equivalent to step in HalfCheetahEnv, but with different rewards.\n\n        Args:\n            action (np.ndarray): The action to take in the environment.\n\n        Raises:\n            ValueError: If the current direction is not 1.0 or -1.0.\n\n        Returns:\n            tuple:\n                * observation (np.ndarray): The observation of the environment.\n                * reward (float): The reward acquired at this time step.\n                * done (boolean): Whether the environment was completed at this\n                    time step. Always False for this environment.\n                * infos (dict):\n                    * reward_forward (float): Reward for moving, ignoring the\n                        control cost.\n                    * reward_ctrl (float): The reward for acting i.e. the\n                        control cost (always negative).\n                    * task_dir (float): Target direction. 1.0 for forwards,\n                        -1.0 for backwards.\n\n        \"\"\"\n        xposbefore = self.sim.data.qpos[0]\n        self.do_simulation(action, self.frame_skip)\n        xposafter = self.sim.data.qpos[0]\n\n        forward_vel = (xposafter - xposbefore) / self.dt\n        forward_reward = self._task['direction'] * forward_vel\n        ctrl_cost = 0.5 * 1e-1 * np.sum(np.square(action))\n\n        observation = self._get_obs()\n        reward = forward_reward - ctrl_cost\n        done = False\n        if self._task['direction'] == 1.:\n            task_name = 'fowrad'\n        elif self._task['direction'] == -1.:\n            task_name = 'backward'\n        else:\n            raise ValueError('task direction should be 1. or -1.')\n        infos = dict(reward_forward=np.asarray([forward_reward]),\n                     reward_ctrl=np.asarray([-ctrl_cost]),\n                     task_dir=np.asarray([self._task['direction']]),\n                     task_name=task_name)\n        return observation, reward, done, infos\n\n    def sample_tasks(self, num_tasks):\n        \"\"\"Sample a list of `num_tasks` tasks.\n\n        Args:\n            num_tasks (int): Number of tasks to sample.\n\n        Returns:\n            list[dict[str, float]]: A list of \"tasks,\" where each task is a\n                dictionary containing a single key, \"direction\", mapping to -1\n                or 1.\n\n        \"\"\"\n        directions = (\n            2 * self.np_random.binomial(1, p=0.5, size=(num_tasks, )) - 1)\n        tasks = [{'direction': direction} for direction in directions]\n        return tasks\n\n    def set_task(self, task):\n        \"\"\"Reset with a task.\n\n        Args:\n            task (dict[str, float]): A task (a dictionary containing a single\n                key, \"direction\", mapping to -1 or 1).\n\n        \"\"\"\n        self._task = task\n", "path": "src/garage/envs/mujoco/half_cheetah_dir_env.py"}]}