mirror of
https://github.com/bulletphysics/bullet3
synced 2024-12-14 05:40:05 +00:00
175 lines
5.7 KiB
Python
175 lines
5.7 KiB
Python
import gym, gym.spaces, gym.utils, gym.utils.seeding
|
|
import numpy as np
|
|
import pybullet
|
|
import os
|
|
|
|
from pybullet_utils import bullet_client
|
|
|
|
from pkg_resources import parse_version
|
|
|
|
try:
|
|
if os.environ["PYBULLET_EGL"]:
|
|
import pkgutil
|
|
except:
|
|
pass
|
|
|
|
class MJCFBaseBulletEnv(gym.Env):
|
|
"""
|
|
Base class for Bullet physics simulation loading MJCF (MuJoCo .xml) environments in a Scene.
|
|
These environments create single-player scenes and behave like normal Gym environments, if
|
|
you don't use multiplayer.
|
|
"""
|
|
|
|
metadata = {'render.modes': ['human', 'rgb_array'], 'video.frames_per_second': 60}
|
|
|
|
def __init__(self, robot, render=False):
|
|
self.scene = None
|
|
self.physicsClientId = -1
|
|
self.ownsPhysicsClient = 0
|
|
self.camera = Camera(self)
|
|
self.isRender = render
|
|
self.robot = robot
|
|
self.seed()
|
|
self._cam_dist = 3
|
|
self._cam_yaw = 0
|
|
self._cam_pitch = -30
|
|
self._render_width = 320
|
|
self._render_height = 240
|
|
|
|
self.action_space = robot.action_space
|
|
self.observation_space = robot.observation_space
|
|
#self.reset()
|
|
|
|
def configure(self, args):
|
|
self.robot.args = args
|
|
|
|
def seed(self, seed=None):
|
|
self.np_random, seed = gym.utils.seeding.np_random(seed)
|
|
self.robot.np_random = self.np_random # use the same np_randomizer for robot as for env
|
|
return [seed]
|
|
|
|
def reset(self):
|
|
if (self.physicsClientId < 0):
|
|
self.ownsPhysicsClient = True
|
|
|
|
if self.isRender:
|
|
self._p = bullet_client.BulletClient(connection_mode=pybullet.GUI)
|
|
else:
|
|
self._p = bullet_client.BulletClient()
|
|
self._p.resetSimulation()
|
|
self._p.setPhysicsEngineParameter(deterministicOverlappingPairs=1)
|
|
#optionally enable EGL for faster headless rendering
|
|
try:
|
|
if os.environ["PYBULLET_EGL"]:
|
|
con_mode = self._p.getConnectionInfo()['connectionMethod']
|
|
if con_mode==self._p.DIRECT:
|
|
egl = pkgutil.get_loader('eglRenderer')
|
|
if (egl):
|
|
self._p.loadPlugin(egl.get_filename(), "_eglRendererPlugin")
|
|
else:
|
|
self._p.loadPlugin("eglRendererPlugin")
|
|
except:
|
|
pass
|
|
self.physicsClientId = self._p._client
|
|
self._p.configureDebugVisualizer(pybullet.COV_ENABLE_GUI, 0)
|
|
|
|
if self.scene is None:
|
|
self.scene = self.create_single_player_scene(self._p)
|
|
if not self.scene.multiplayer and self.ownsPhysicsClient:
|
|
self.scene.episode_restart(self._p)
|
|
|
|
self.robot.scene = self.scene
|
|
|
|
self.frame = 0
|
|
self.done = 0
|
|
self.reward = 0
|
|
dump = 0
|
|
s = self.robot.reset(self._p)
|
|
self.potential = self.robot.calc_potential()
|
|
return s
|
|
|
|
def camera_adjust(self):
|
|
pass
|
|
|
|
def render(self, mode='human', close=False):
|
|
|
|
if mode == "human":
|
|
self.isRender = True
|
|
if self.physicsClientId>=0:
|
|
self.camera_adjust()
|
|
|
|
if mode != "rgb_array":
|
|
return np.array([])
|
|
|
|
base_pos = [0, 0, 0]
|
|
if (hasattr(self, 'robot')):
|
|
if (hasattr(self.robot, 'body_real_xyz')):
|
|
base_pos = self.robot.body_real_xyz
|
|
if (self.physicsClientId>=0):
|
|
view_matrix = self._p.computeViewMatrixFromYawPitchRoll(cameraTargetPosition=base_pos,
|
|
distance=self._cam_dist,
|
|
yaw=self._cam_yaw,
|
|
pitch=self._cam_pitch,
|
|
roll=0,
|
|
upAxisIndex=2)
|
|
proj_matrix = self._p.computeProjectionMatrixFOV(fov=60,
|
|
aspect=float(self._render_width) /
|
|
self._render_height,
|
|
nearVal=0.1,
|
|
farVal=100.0)
|
|
(_, _, px, _, _) = self._p.getCameraImage(width=self._render_width,
|
|
height=self._render_height,
|
|
viewMatrix=view_matrix,
|
|
projectionMatrix=proj_matrix,
|
|
renderer=pybullet.ER_BULLET_HARDWARE_OPENGL)
|
|
|
|
self._p.configureDebugVisualizer(self._p.COV_ENABLE_SINGLE_STEP_RENDERING,1)
|
|
else:
|
|
px = np.array([[[255,255,255,255]]*self._render_width]*self._render_height, dtype=np.uint8)
|
|
rgb_array = np.array(px, dtype=np.uint8)
|
|
rgb_array = np.reshape(np.array(px), (self._render_height, self._render_width, -1))
|
|
rgb_array = rgb_array[:, :, :3]
|
|
return rgb_array
|
|
|
|
def close(self):
|
|
if (self.ownsPhysicsClient):
|
|
if (self.physicsClientId >= 0):
|
|
self._p.disconnect()
|
|
self.physicsClientId = -1
|
|
|
|
def HUD(self, state, a, done):
|
|
pass
|
|
|
|
# def step(self, *args, **kwargs):
|
|
# if self.isRender:
|
|
# base_pos=[0,0,0]
|
|
# if (hasattr(self,'robot')):
|
|
# if (hasattr(self.robot,'body_xyz')):
|
|
# base_pos = self.robot.body_xyz
|
|
# # Keep the previous orientation of the camera set by the user.
|
|
# #[yaw, pitch, dist] = self._p.getDebugVisualizerCamera()[8:11]
|
|
# self._p.resetDebugVisualizerCamera(3,0,0, base_pos)
|
|
#
|
|
#
|
|
# return self.step(*args, **kwargs)
|
|
if parse_version(gym.__version__) < parse_version('0.9.6'):
|
|
_render = render
|
|
_reset = reset
|
|
_seed = seed
|
|
|
|
|
|
class Camera:
|
|
|
|
def __init__(self, env):
|
|
self.env = env
|
|
pass
|
|
|
|
def move_and_look_at(self, i, j, k, x, y, z):
|
|
lookat = [x, y, z]
|
|
camInfo = self.env._p.getDebugVisualizerCamera()
|
|
|
|
distance = camInfo[10]
|
|
pitch = camInfo[9]
|
|
yaw = camInfo[8]
|
|
self.env._p.resetDebugVisualizerCamera(distance, yaw, pitch, lookat)
|