Multiprocessing OpenAI ROS environments w/ python multiprocessing library
Hello,
I am trying to train a Turtlebot agent using the OpenAI_ROS package. While my goal is forking multiple processes to create multiple gazebo environments, I created an only single process, to start from a simple scenario.
OpenAI baseline package provides SubprocVecEnv(), which depends on the python multiprocessing library. I was able to initialize a TurtleBot3WorldEnv using SubprocVecEnv().
However, for some reason, the Turtlebot3 spawned in the world cannot subscribe to messages even though they are all available in ROS. For example, I can echo /odom and /scan, but I cannot subscribe to them from TurtleBot3Env. Instead, I get an error message: " Current /odom not ready yet, retrying for getting doom".
I use ROS noetic w/ Ubuntu 2020 Does anyone know how to solve this issue?
Best,
env_fn below is lambda: make_env() which is a simple wrapper of gym.make()
import multiprocessing as mp
import os
import numpy as np
from .vec_env import VecEnv, CloudpickleWrapper, clear_mpi_env_vars
import time
class SubprocVecEnv(VecEnv):
def __init__(self, env_fns, spaces=None, context='fork'): #env_fns: iterable of callables - functions that create environments to run in subprocesses. Need to be cloud-pickleable
self.waiting = False
self.closed = False
nenvs = len(env_fns)
ctx = mp.get_context(context)
self.remotes, self.work_remotes = zip(*[ctx.Pipe() for _ in range(nenvs)]) # remote (parent) and work_remote (child) are connected by a pipe
self.ps = [ctx.Process(target=worker, args=(work_remote, remote, CloudpickleWrapper(env_fn)))
for (work_remote, remote, env_fn) in zip(self.work_remotes, self.remotes, env_fns)]
for p in self.ps:
p.daemon = True # if the main process crashes, we should not cause things to hang
with clear_mpi_env_vars():
p.start()
for remote in self.work_remotes:
remote.close()
self.remotes[0].send(('get_spaces_spec', None))
observation_space, action_space, self.spec = self.remotes[0].recv()
self.viewer = None
VecEnv.__init__(self, len(env_fns), observation_space, action_space)
def worker(remote, parent_remote, env_fn_wrapper):
parent_remote.close()
env = env_fn_wrapper.x()
try:
while True:
cmd, data = remote.recv()
if cmd == 'step':
ob, reward, done, info = env.step(data)
if done:
ob = env.reset()
remote.send((ob, reward, done, info))
elif cmd == 'reset':
ob = env.reset()
remote.send(ob)
elif cmd == 'render':
remote.send(env.render(mode='rgb_array'))
elif cmd == 'close':
remote.close()
break
elif cmd == 'get_spaces_spec':
remote.send((env.observation_space, env.action_space, env.spec))
else:
raise NotImplementedError
except KeyboardInterrupt:
print('SubprocVecEnv worker: got KeyboardInterrupt')
finally:
env.close()
Althoug it does not answer your question directly, there is a new package "robo_gym" which targets distributed RL training: https://github.com/jr-robotics/robo-gym. At least, it seems to have more recent support than openai_ros
It seems that the new package supports ROS melodic and kinetic at this point. I am having several errors during the package installation... Thanks for your answer though.
I was able to build it in melodic, but I agree it lacks in providing examples and tutorials yet. Do you need to use noetic? I think it's quite early, there are a lot of packages missing and building packages from source often raises python issues for me.
Nothing wrong with the package. I think the problem is coming from two different python versions. That is, melodic is supported by python 2 while noetic uses python3. It seems that the new package was looking for python2 at some point. I can go back to melodic. But, were you able to use openai-baseline and melodic together? The former is made of python3 while the latter use python2. Besides, I agree with you that it would be better if the author could provide more examples and tutorials.
I did not try openAI baselines but openAI gym is working for me. Besides that, you can find instructions to set up Melodic with Python3, but I never tried it by myself so far. I think robo-gym uses docker, too.