diff --git a/docs/conf.py b/docs/conf.py index 02628a3ec..82e015919 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -55,6 +55,7 @@ warnings.simplefilter("ignore", SimulatorInterfaceWarning) import scenic.simulators.carla.model import scenic.simulators.lgsvl.model + import scenic.simulators.maniskill.model import scenic.simulators.metadrive.model veneer.deactivate() @@ -108,7 +109,15 @@ autosummary_generate = True autodoc_inherit_docstrings = False autodoc_member_order = "bysource" -autodoc_mock_imports = ["carla", "lgsvl", "metadrive"] +autodoc_mock_imports = [ + "carla", + "lgsvl", + "metadrive", + "mani_skill", + "torch", + "sapien", + "gymnasium", +] autodoc_typehints = "description" autodoc_type_aliases = { "Vectorlike": "`scenic.domains.driving.roads.Vectorlike`", diff --git a/pyproject.toml b/pyproject.toml index 294e79071..c21ee3150 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,7 +63,7 @@ maniskill = [ "mani-skill >= 3.0.0b20", "torch >= 2.0.0", "sapien >= 3.0.0", - "gymnasium >= 0.29.0", + "gymnasium >= 1.0.0", "coacd >= 1.0.0", ] test = [ # minimum dependencies for running tests (used for tox virtualenvs) diff --git a/src/scenic/core/utils.py b/src/scenic/core/utils.py index 9817843f5..e5488f3ed 100644 --- a/src/scenic/core/utils.py +++ b/src/scenic/core/utils.py @@ -19,6 +19,19 @@ sqrt2 = math.sqrt(2) + +def buildingScenicDocumentation(): + """Return True if Scenic's Sphinx docs are currently being built. + + This relies on docs/conf.py setting ``sphinx._buildingScenicDocs = True`` + before importing Scenic, and avoids importing Sphinx here. + """ + sphinx = sys.modules.get("sphinx") + if sphinx is None: + return False + return bool(getattr(sphinx, "_buildingScenicDocs", False)) + + if sys.version_info >= (3, 12): from itertools import batched else: diff --git a/src/scenic/simulators/lgsvl/model.scenic b/src/scenic/simulators/lgsvl/model.scenic index 902566f94..d1b8f27cb 100644 --- a/src/scenic/simulators/lgsvl/model.scenic +++ b/src/scenic/simulators/lgsvl/model.scenic @@ -2,15 +2,14 @@ from scenic.domains.driving.model import * from scenic.simulators.lgsvl.behaviors import * +from scenic.core.utils import buildingScenicDocumentation # Deprecation error on import, but allow for doc building. -try: - import sphinx - if not sphinx._buildingScenicDocs: - raise RuntimeError("The LGSVL Simulator interface was deprecated in Scenic 3." - " To continue to use the interface, please use Scenic 2.") -except ModuleNotFoundError: - pass +if not buildingScenicDocumentation(): + raise RuntimeError( + "The LGSVL Simulator interface was deprecated in Scenic 3." + " To continue to use the interface, please use Scenic 2." + ) try: import lgsvl diff --git a/src/scenic/simulators/maniskill/simulator.py b/src/scenic/simulators/maniskill/simulator.py index ba71aced8..f8e2ad711 100644 --- a/src/scenic/simulators/maniskill/simulator.py +++ b/src/scenic/simulators/maniskill/simulator.py @@ -5,26 +5,35 @@ import tempfile from typing import Optional +import numpy as np + +from scenic.core.simulators import Simulation, Simulator +from scenic.core.utils import buildingScenicDocumentation +from scenic.core.vectors import Orientation, Vector + +try: + import mani_skill +except ImportError as e: + raise ModuleNotFoundError( + "ManiSkill scenarios require the optional ManiSkill dependencies. " + "Install with `pip install scenic[maniskill]`." + ) from e + import gymnasium as gym 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.building.ground import build_ground from mani_skill.utils.registration import register_env -import numpy as np import sapien import torch -from scenic.core.simulators import Simulation, Simulator -from scenic.core.vectors import Orientation, Vector - # Default camera configuration DEFAULT_CAMERA_EYE = [0.0, -1.0, 1.0] DEFAULT_CAMERA_TARGET = [0.0, 0.0, 0.0] DEFAULT_ROBOT_POSITION = [0.0, 0.0, 0.0] -@register_env("ScenicEnv") class ScenicEnv(BaseEnv): """Custom ManiSkill environment for Scenic scenarios.""" @@ -52,9 +61,7 @@ def _default_sensor_configs(self): return self.scene_camera_configs # Fallback to default camera configuration - pose = sapien_utils.look_at( - eye=DEFAULT_CAMERA_EYE, target=DEFAULT_CAMERA_TARGET - ) + pose = sapien_utils.look_at(eye=DEFAULT_CAMERA_EYE, target=DEFAULT_CAMERA_TARGET) return [ CameraConfig( "base_camera", @@ -68,9 +75,7 @@ def _default_sensor_configs(self): ) ] - def _load_agent( - self, options: dict, initial_agent_poses=None, build_separate=False - ): + def _load_agent(self, options: dict, initial_agent_poses=None, build_separate=False): """Load the robot agent into the scene.""" super()._load_agent(options, sapien.Pose(p=DEFAULT_ROBOT_POSITION)) @@ -194,6 +199,11 @@ def compute_normalized_dense_reward(self, obs, action, info: dict): return 1.0 +# Register the ManiSkill environment in normal runs, but skip this during doc builds. +if not buildingScenicDocumentation(): + ScenicEnv = register_env("ScenicEnv")(ScenicEnv) + + class ManiSkillSimulator(Simulator): """Simulator interface for ManiSkill.""" diff --git a/src/scenic/syntax/translator.py b/src/scenic/syntax/translator.py index 994e65b8b..109744cce 100644 --- a/src/scenic/syntax/translator.py +++ b/src/scenic/syntax/translator.py @@ -41,7 +41,7 @@ from scenic.core.errors import InvalidScenarioError, PythonCompileError from scenic.core.lazy_eval import needsLazyEvaluation import scenic.core.pruning as pruning -from scenic.core.utils import cached_property +from scenic.core.utils import buildingScenicDocumentation, cached_property from scenic.syntax.compiler import compileScenicAST from scenic.syntax.parser import parse_string import scenic.syntax.veneer as veneer @@ -439,8 +439,7 @@ def __setstate__(self, state): # getting confused. (Autodoc doesn't expect modules to have that attribute, # and we can't del it.) We only do this during Sphinx runs since it seems to # sometimes break pickling of the modules. -sphinx = sys.modules.get("sphinx") -buildingDocs = sphinx and getattr(sphinx, "_buildingScenicDocs", False) +buildingDocs = buildingScenicDocumentation() if buildingDocs: ScenicModule.__module__ = None