qgallouedec / panda-gym

Set of robotic environments based on PyBullet physics engine and gymnasium.
MIT License
548 stars 115 forks source link

Fix rendering for `render_mode=human` #56

Closed qgallouedec closed 1 year ago

qgallouedec commented 1 year ago

Close #54 Close #55

qgallouedec commented 1 year ago

@jonasreiher can you review these changes? Thanks!

jonasreiher commented 1 year ago

This addresses my concerns raised in #54 and works as expected. However, I'm no longer sure this is the way to go.

With render_mode='human', when calling env.render(), gymnasium raises a warning indicating that human rendering should indeed return None:

.../lib/python3.8/site-packages/gymnasium/utils/passive_env_checker.py:288: UserWarning: WARN: Human rendering should return `None`, got <class 'numpy.ndarray'>

So maybe we should not enable RGB-rendering with render_mode='human' but instead enable (optionally) high-quality OpenGL rendering with render_mode='rgb_array'?

qgallouedec commented 1 year ago

So maybe we should not enable RGB-rendering with render_mode='human' but instead enable (optionally) high-quality OpenGL rendering with render_mode='rgb_array'?

something like that?

gym.make("PandaReach-v3", render_mode="rgb_array", "renderer"="OpenGL")

The ideal would be to find a way to run OpenGL in headless mode.

jonasreiher commented 1 year ago

something like that?

gym.make("PandaReach-v3", render_mode="rgb_array", "renderer"="OpenGL")

Exactly.

I agree that headless OpenGL would be ideal. I'm currently using pyvirtualdisplay for headless runs but rendering is again about four times slower this way. I have no idea how to accomplish this, though.

qgallouedec commented 1 year ago

From what I can see, it's far from being easy. Let's add the renderer arg in make in the meanwhile. Default will be "tiny".

qgallouedec commented 1 year ago

I've moved the render args into the constructor. I think this is the proper way to proceed considering the gymnasium doc.

import gymnasium as gym
import panda_gym

env = gym.make("PandaReach-v3", render_mode="rgb_array", render_width=84, render_height=84)
env.reset()
image = env.render()
assert image.shape == (84, 84, 3)

I've also added the renderer arg:

import gymnasium as gym
import panda_gym

env = gym.make("PandaReach-v3", render_mode="rgb_array", renderer="OpenGL")
env.reset()
image = env.render()
assert image.shape == (480, 720, 3)
qgallouedec commented 1 year ago

Thanks for your help @jonasreiher. I'm doing some more checking and hope to merge it tomorrow.

jonasreiher commented 1 year ago

Thanks for your help @jonasreiher. I'm doing some more checking and hope to merge it tomorrow.

Thank you!

qgallouedec commented 1 year ago

Now it's LGTM :100:

jonasreiher commented 1 year ago

When is version 3.0.4 with this change expected to be released?

qgallouedec commented 1 year ago

Right now