Source code for mani_skill.envs.scenes.base_env

from typing import Any, Union

import numpy as np
import sapien as sapien
import sapien.physx as physx
import torch
from sapien import Pose

from mani_skill.agents.robots import Fetch, Panda
from mani_skill.envs.sapien_env import BaseEnv
from mani_skill.sensors.camera import CameraConfig
from mani_skill.utils import sapien_utils
from mani_skill.utils.registration import register_env
from mani_skill.utils.scene_builder import SceneBuilder
from mani_skill.utils.scene_builder.registration import REGISTERED_SCENE_BUILDERS
from mani_skill.utils.structs.types import GPUMemoryConfig, SimConfig


@register_env("SceneManipulation-v1", max_episode_steps=200)
[docs]class SceneManipulationEnv(BaseEnv): """ A base environment for simulating manipulation tasks in more complex scenes. Creating this base environment is only useful for explorations/visualization, there are no success/failure metrics or rewards. Args: robot_uids: Which robot to place into the scene. Default is "fetch" fixed_scene: When True, will never reconfigure the environment during resets unless you run env.reset(seed=seed, options=dict(reconfigure=True)) and explicitly reconfigure. If False, will reconfigure every reset. scene_builder_cls: Scene builder class to build a scene with. Default is ReplicaCAD. Furthermore, any of the AI2THOR SceneBuilders are supported in this environment. build_config_idxs (optional): which build configs (static builds) to sample. Your scene_builder_cls may or may not require these. init_config_idxs (optional): which init configs (additional init options) to sample. Your scene_builder_cls may or may not require these. """
[docs] SUPPORTED_ROBOTS = ["panda", "fetch"]
[docs] agent: Union[Panda, Fetch]
def __init__( self, *args, robot_uids="fetch", scene_builder_cls: Union[str, SceneBuilder] = "ReplicaCAD", build_config_idxs=None, init_config_idxs=None, num_envs=1, reconfiguration_freq=None, **kwargs ): if isinstance(scene_builder_cls, str): scene_builder_cls = REGISTERED_SCENE_BUILDERS[ scene_builder_cls ].scene_builder_cls
[docs] self.scene_builder: SceneBuilder = scene_builder_cls(self)
[docs] self.build_config_idxs = build_config_idxs
[docs] self.init_config_idxs = init_config_idxs
if reconfiguration_freq is None: if num_envs == 1: reconfiguration_freq = 1 else: reconfiguration_freq = 0 super().__init__( *args, robot_uids=robot_uids, reconfiguration_freq=reconfiguration_freq, num_envs=num_envs, **kwargs ) @property
[docs] def _default_sim_config(self): return SimConfig( spacing=50, gpu_memory_config=GPUMemoryConfig( found_lost_pairs_capacity=2**25, max_rigid_patch_count=2**21, max_rigid_contact_count=2**23, ), )
[docs] def reset(self, seed=None, options=None): if options is None: options = dict(reconfigure=False) self._set_episode_rng(seed, options.get("env_idx", torch.arange(self.num_envs))) if "reconfigure" in options and options["reconfigure"]: self.build_config_idxs = options.get( "build_config_idxs", self.build_config_idxs ) self.init_config_idxs = options.get("init_config_idxs", None) else: assert ( "build_config_idxs" not in options ), "options dict cannot contain build_config_idxs without reconfigure=True" self.init_config_idxs = options.get( "init_config_idxs", self.init_config_idxs ) if isinstance(self.build_config_idxs, int): self.build_config_idxs = [self.build_config_idxs] if isinstance(self.init_config_idxs, int): self.init_config_idxs = [self.init_config_idxs] return super().reset(seed, options)
[docs] def _load_lighting(self, options: dict): if self.scene_builder.builds_lighting: return return super()._load_lighting(options)
[docs] def _load_agent(self, options: dict): super()._load_agent( options, self.scene_builder.robot_initial_pose, )
[docs] def _load_scene(self, options: dict): if self.scene_builder.build_configs is not None: self.scene_builder.build( self.build_config_idxs if self.build_config_idxs is not None else self.scene_builder.sample_build_config_idxs() ) else: self.scene_builder.build()
[docs] def _initialize_episode(self, env_idx: torch.Tensor, options: dict): with torch.device(self.device): if self.scene_builder.init_configs is not None: self.scene_builder.initialize( env_idx, ( self.init_config_idxs if self.init_config_idxs is not None else self.scene_builder.sample_init_config_idxs() ), ) else: self.scene_builder.initialize(env_idx)
[docs] def evaluate(self) -> dict: return dict()
[docs] def compute_dense_reward(self, obs: Any, action: torch.Tensor, info: dict): return 0
[docs] def compute_normalized_dense_reward( self, obs: Any, action: torch.Tensor, info: dict ): return self.compute_dense_reward(obs=obs, action=action, info=info) / 1
@property
[docs] def _default_sensor_configs(self): if self.robot_uids == "fetch": return [] pose = sapien_utils.look_at([0.3, 0, 0.6], [-0.1, 0, 0.1]) return [CameraConfig("base_camera", pose, 128, 128, np.pi / 2, 0.01, 100)]
@property
[docs] def _default_human_render_camera_configs(self): if self.robot_uids == "fetch": room_camera_pose = sapien_utils.look_at([2.5, -2.5, 3], [0.0, 0.0, 0]) room_camera_config = CameraConfig( "render_camera", room_camera_pose, 512, 512, 1, 0.01, 100, ) robot_camera_pose = sapien_utils.look_at([2, 0, 1], [0, 0, -1]) robot_camera_config = CameraConfig( "robot_render_camera", robot_camera_pose, 512, 512, 1.5, 0.01, 100, mount=self.agent.torso_lift_link, ) return [room_camera_config, robot_camera_config] if self.robot_uids == "panda": pose = sapien_utils.look_at([0.4, 0.4, 0.8], [0.0, 0.0, 0.4]) else: pose = sapien_utils.look_at([0, 10, -3], [0, 0, 0]) return CameraConfig("render_camera", pose, 512, 512, 1, 0.01, 100)