1import gymnasium as gym
2import fancy_gym
3
4
5def example_meta(env_id="fish-swim", seed=1, iterations=1000, render=True):
6 """
7 Example for running a MetaWorld based env in the step based setting.
8 The env_id has to be specified as `task_name-v2`. V1 versions are not supported and we always
9 return the observable goal version.
10 All tasks can be found here: https://arxiv.org/pdf/1910.10897.pdf or https://meta-world.github.io/
11
12 Args:
13 env_id: `task_name-v2`
14 seed: seed for deterministic behaviour (TODO: currently not working due to an issue in MetaWorld code)
15 iterations: Number of rollout steps to run
16 render: Render the episode
17
18 Returns:
19
20 """
21 env = gym.make(env_id)
22 rewards = 0
23 obs = env.reset(seed=seed)
24 print("observation shape:", env.observation_space.shape)
25 print("action shape:", env.action_space.shape)
26
27 for i in range(iterations):
28 ac = env.action_space.sample()
29 if render:
30 # THIS NEEDS TO BE SET TO FALSE FOR NOW, BECAUSE THE INTERFACE FOR RENDERING IS DIFFERENT TO BASIC GYM
31 # TODO: Remove this, when Metaworld fixes its interface.
32 env.render(False)
33 obs, reward, terminated, truncated, info = env.step(ac)
34 rewards += reward
35 if terminated or truncated:
36 print(env_id, rewards)
37 rewards = 0
38 obs = env.reset()
39
40 env.close()
41 del env
42
43
44def example_custom_meta_and_mp(seed=1, iterations=1, render=True):
45 """
46 Example for running a custom movement primitive based environments.
47 Our already registered environments follow the same structure.
48 Hence, this also allows to adjust hyperparameters of the movement primitives.
49 Yet, we recommend the method above if you are just interested in chaining those parameters for existing tasks.
50 We appreciate PRs for custom environments (especially MP wrappers of existing tasks)
51 for our repo: https://github.com/ALRhub/fancy_gym/
52 Args:
53 seed: seed for deterministic behaviour (TODO: currently not working due to an issue in MetaWorld code)
54 iterations: Number of rollout steps to run
55 render: Render the episode (TODO: currently not working due to an issue in MetaWorld code)
56
57 Returns:
58
59 """
60
61 # Base MetaWorld name, according to structure of above example
62 base_env_id = "metaworld/button-press-v2"
63
64 # Replace this wrapper with the custom wrapper for your environment by inheriting from the RawInterfaceWrapper.
65 # You can also add other gym.Wrappers in case they are needed.
66 wrappers = [fancy_gym.meta.goal_object_change_mp_wrapper.MPWrapper]
67 # # For a ProMP
68 # trajectory_generator_kwargs = {'trajectory_generator_type': 'promp'}
69 # phase_generator_kwargs = {'phase_generator_type': 'linear'}
70 # controller_kwargs = {'controller_type': 'metaworld'}
71 # basis_generator_kwargs = {'basis_generator_type': 'zero_rbf',
72 # 'num_basis': 5,
73 # 'num_basis_zero_start': 1
74 # }
75
76 # For a DMP
77 trajectory_generator_kwargs = {'trajectory_generator_type': 'dmp'}
78 phase_generator_kwargs = {'phase_generator_type': 'exp',
79 'alpha_phase': 2}
80 controller_kwargs = {'controller_type': 'metaworld'}
81 basis_generator_kwargs = {'basis_generator_type': 'rbf',
82 'num_basis': 5
83 }
84 env = fancy_gym.make_bb(env_id=base_env_id, wrappers=wrappers, black_box_kwargs={},
85 traj_gen_kwargs=trajectory_generator_kwargs, controller_kwargs=controller_kwargs,
86 phase_kwargs=phase_generator_kwargs, basis_kwargs=basis_generator_kwargs,
87 seed=seed)
88
89 # This renders the full MP trajectory
90 # It is only required to call render() once in the beginning, which renders every consecutive trajectory.
91 # Resetting to no rendering, can be achieved by render(mode=None).
92 # It is also possible to change them mode multiple times when
93 # e.g. only every nth trajectory should be displayed.
94 if render:
95 raise ValueError("Metaworld render interface bug does not allow to render() fixes its interface. "
96 "A temporary workaround is to alter their code in MujocoEnv render() from "
97 "`if not offscreen` to `if not offscreen or offscreen == 'human'`.")
98 # TODO: Remove this, when Metaworld fixes its interface.
99 # env.render(mode="human")
100
101 rewards = 0
102 obs = env.reset()
103
104 # number of samples/full trajectories (multiple environment steps)
105 for i in range(iterations):
106 ac = env.action_space.sample()
107 obs, reward, terminated, truncated, info = env.step(ac)
108 rewards += reward
109
110 if terminated or truncated:
111 print(base_env_id, rewards)
112 rewards = 0
113 obs = env.reset()
114
115 env.close()
116 del env
117
118
119if __name__ == '__main__':
120 # Disclaimer: MetaWorld environments require the seed to be specified in the beginning.
121 # Adjusting it afterwards with env.seed() is not recommended as it may not affect the underlying behavior.
122
123 # For rendering it might be necessary to specify your OpenGL installation
124 # export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libGLEW.so
125 render = False
126
127 # # Standard Meta world tasks
128 example_meta("metaworld/button-press-v2", seed=10, iterations=500, render=render)
129
130 # # MP + MetaWorld hybrid task provided in the our framework
131 example_meta("metaworld_ProMP/ButtonPress-v2", seed=10, iterations=1, render=render)
132 #
133 # # Custom MetaWorld task
134 example_custom_meta_and_mp(seed=10, iterations=1, render=render)