SUMMARY: All I want to do is use the DummyVecEnv constructor to wrap my gym environment i.e.
env = DummyVecEnv([lambda: env]) but I keep getting errors when doing this. Currently using https://pypi.org/project/gym-super-mario-bros/ as a gym wrapper for Super Mario. I have a feeling I am misunderstanding what arguments I am supposed to provide the constructor but I am new to python and am having difficulty understanding what I'm missing.
I'm having difficulty using the DummyVecEnv constructor around the environment that I'm returning from gym_super_mario_bros.make(). I keep getting an error "You tried to create multiple environments, but the function to create them returned the same instance instead of creating different objects".
I initially tried to wrap my environment in a DummyVecEnv the way I have seen it done on many forums:
env = gym_super_mario_bros.make("SuperMarioBros-v0")
env = JoypadSpace(env, SIMPLE_MOVEMENT)
env = GrayScaleObservation(env, keep_dim=True)
env = DummyVecEnv([lambda: env]) #This line errors
but I got this error:
File c:\Users\truem\AppData\Local\Programs\Python\Python311\Lib\site-packages\stable_baselines3\common\vec_env\dummy_vec_env.py:30, in DummyVecEnv.init(self, env_fns)
29 def init(self, env_fns: List[Callable[[], gym.Env]]):
---> 30 self.envs = [_patch_env(fn()) for fn in env_fns]
31 if len(set([id(env.unwrapped) for env in self.envs])) != len(self.envs):
32 raise ValueError(
33 "You tried to create multiple environments, but the function to create them returned the same instance "
34 "instead of creating different objects. "(...)
39 "Please read https://github.com/DLR-RM/stable-baselines3/issues/1151 for more information."
40 )
So then I tried to follow the fix listed at the github link as well as the examples provided in the documentation
https://stable-baselines.readthedocs.io/en/master/guide/examples.html
I went ahead and created a new helper function create_default_environment which should create new env instances and return them, but despite this it still isn't working.
This is how my code looks now:
#wrap my env creation in a function
def create_default_environment():
newEnv = gym_super_mario_bros.make("SuperMarioBros-v0")
newEnv = JoypadSpace(newEnv, SIMPLE_MOVEMENT)
return GrayScaleObservation(newEnv, keep_dim=True)
#Create lambda in a list which calls helper function
env = DummyVecEnv([lambda: create_default_environment()]) #still failing
I went ahead and wrapped my initial env construction inside a helper function create_default_environment() which I have verified returns a new env instance with every call. I then used that wrapper to plug into the DummyVecEnv constructor:
env = DummyVecEnv([lambda: create_default_environment()])
But the compiler still complains that my list of functions passed in does not return new instances.
I've been trying to emulate what I see in the example code that baselines provides:
from stable_baselines.common.vec_env import DummyVecEnv, VecNormalize
from stable_baselines import PPO2
env = DummyVecEnv(\[lambda: gym.make("HalfCheetahBulletEnv-v0")]) #why does this work but mine does not?
but I'm not sure what I'm doing wrong. New to python so excuse me if there's something obvious I'm missing.