Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down Expand Up @@ -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`",
Expand Down
22 changes: 22 additions & 0 deletions docs/simulators.rst
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,28 @@ See the paper and `scenic.simulators.gta` for documentation.
Importing scenes into GTA V and capturing rendered images requires a GTA V plugin, which you can find `here <https://github.com/xyyue/scenic2gta>`__.


ManiSkill
---------

Scenic supports integration with the `ManiSkill <https://maniskill.readthedocs.io/>`_
simulator as an optional dependency, enabling users to describe robotic scenarios.

You can install it with:

.. code-block:: console

python -m pip install scenic[maniskill]

.. note::

ManiSkill currently best supports Linux systems. On Windows and macOS, ManiSkill has
limited support. On macOS, additional setup may be required. See the
`ManiSkill installation instructions <https://maniskill.readthedocs.io/en/latest/user_guide/getting_started/installation.html>`_.

For more information, refer to the documentation of the
`scenic.simulators.maniskill` module.


Webots
------

Expand Down
3 changes: 3 additions & 0 deletions examples/maniskill/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# ManiSkill Examples

This directory contains example scenarios for the [ManiSkill](https://github.com/haosulab/ManiSkill) robotics simulator.
28 changes: 28 additions & 0 deletions examples/maniskill/robot_arm.scenic
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
model scenic.simulators.maniskill.model

# Create ground plane
ground = new Ground with position (0, 0, -0.920)

# Create Panda robot arm with a neutral pose
# Joint angles: [joint1, joint2, joint3, joint4, joint5, joint6, joint7, gripper_left, gripper_right]
panda = new Robot,
with uuid "panda",
with jointAngles [0.0, 22.5 deg, 0.0, -90 deg, 0.0, 112.5 deg, 45 deg, 0.04, 0.04]

# Create camera positioned to view the robot and cube
camera = new Camera,
at (-0.64, -0.4, 0.758),
with name "base_camera",
with img_width 640,
with img_height 480,
with fov 1.0

# Create a cube in front of the robot (within reach)
cube = new ManiskillObject on ground,
at (0.4, 0.0, 0.035),
with name "target_cube",
with shape BoxShape(),
with width 0.05,
with length 0.05,
with height 0.05,
with color [1.0, 0.5, 0.0, 1.0] # Orange cube
33 changes: 33 additions & 0 deletions examples/maniskill/stacked_cubes.scenic
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
model scenic.simulators.maniskill.model

# Create ground plane
ground = new Ground with position (0, 0, -0.920)

# Create three cubes stacked on top of each other
# Bottom cube (red)
cube1 = new ManiskillObject on ground,
at (0, 0, 0.035),
with name "cube1",
with shape BoxShape(),
with width 0.07,
with length 0.07,
with height 0.07,
with color [0.9, 0.1, 0.1, 1.0]

# Middle cube (green)
cube2 = new ManiskillObject on cube1,
with name "cube2",
with shape BoxShape(),
with width 0.07,
with length 0.07,
with height 0.07,
with color [0.1, 0.9, 0.1, 1.0]

# Top cube (blue)
cube3 = new ManiskillObject on cube2,
with name "cube3",
with shape BoxShape(),
with width 0.07,
with length 0.07,
with height 0.07,
with color [0.1, 0.1, 0.9, 1.0]
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ metadrive = [
"metadrive-simulator >= 0.4.3",
"sumolib >= 1.21.0",
]
maniskill = [
"mani-skill >= 3.0.0b20",
"torch >= 2.0.0",
"sapien >= 3.0.0",
"gymnasium >= 0.29.0",
"coacd >= 1.0.0",
]
test = [ # minimum dependencies for running tests (used for tox virtualenvs)
"pytest >= 7.0.0, <9",
"pytest-cov >= 3.0.0",
Expand Down
13 changes: 13 additions & 0 deletions src/scenic/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
13 changes: 6 additions & 7 deletions src/scenic/simulators/lgsvl/model.scenic
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 13 additions & 0 deletions src/scenic/simulators/maniskill/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""
Interface to the ManiSkill robotics simulator.
"""

# Check if mani_skill is installed and import ManiSkillSimulator only if it is
mani_skill = None
try:
import mani_skill
except ImportError:
pass
if mani_skill:
from .simulator import ManiSkillSimulator
del mani_skill
105 changes: 105 additions & 0 deletions src/scenic/simulators/maniskill/model.scenic
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
"""Scenic world model for robotic manipulation scenarios in ManiSkill.

Global Parameters:
render (bool): Whether to render the simulation in a window. If True, it will open
a window and display the simulation. If False (default), the simulation runs headless.
stride (int): Number of simulation steps between action updates. Default is 1.
"""

try:
from scenic.simulators.maniskill.simulator import ManiSkillSimulator
except ModuleNotFoundError:
# for convenience when testing without the mani_skill package
from scenic.core.simulators import SimulatorInterfaceWarning
import warnings
warnings.warn('The "mani-skill" package is not installed; '
'will not be able to run dynamic simulations',
SimulatorInterfaceWarning)

def ManiSkillSimulator(*args, **kwargs):
"""Dummy simulator to allow compilation without the 'mani-skill' package.

:meta private:
"""
raise RuntimeError('the "mani-skill" package is required to run simulations '
'from this scenario')

param render = False
param stride = 1

simulator ManiSkillSimulator(
render=bool(globalParameters.render),
stride=int(globalParameters.stride),
)

class ManiskillObject(Object):
"""Base class for ManiSkill objects.

Properties:
visualFilename (str or None): Path to a visual mesh file (e.g., .glb, .obj, .usdz).
visualScale (tuple): Scale factor for the visual mesh as (x, y, z).
visualOffset (tuple): Offset for the visual mesh as (x, y, z) to match visual and collision meshes.
kinematic (bool): If True, the object is kinematic (fixed in place).
"""
visualFilename: None
visualScale: (1, 1, 1)
visualOffset: (0, 0, 0)
width: 1
length: 1
height: 1
color: [0.8, 0.8, 0.8, 1.0]
kinematic: False

class Ground(ManiskillObject):
"""The default ground plane from ManiSkill.

This creates a large flat ground plane using ManiSkill's built-in ground builder.
The ground is always kinematic (fixed in place).
"""
name: "ground"
shape: BoxShape()
width: 100
length: 100
height: 0.001
position: (0, 0, -0.0005)
kinematic: True
visualFilename: None
isSimpleGround: True # Specify to ManiSkill that this is the ground plane

class Robot(Object):
"""Robot object (Panda arm by default).

This class represents a robot in the scene. The robot is not physically generated
in the scene (skipGeneration=True) but is used to configure the robot's initial state.

Properties:
uuid (str): Robot type identifier. Default is "panda" for the Franka Emika Panda arm.
jointAngles (list): Initial joint angles for the robot. If empty, uses a default configuration.
"""
position: (10, 0, 0) # Make scenic ignore it for collision checking for now
name: "actor"
uuid: "panda"
jointAngles: []
skipGeneration: True # Don't generate this object in the scene

class Camera(OrientedPoint):
"""Camera configuration for the scene.

Cameras are not physical objects but define viewpoints for rendering and observation.

Properties:
img_width (int): Image width in pixels. Default is 640.
img_height (int): Image height in pixels. Default is 480.
fov (float): Field of view in radians. Default is 1.0.
near (float): Near clipping plane distance. Default is 0.01.
far (float): Far clipping plane distance. Default is 100.0.
shader_pack (str): Shader pack to use for rendering. Default is "rt" (ray tracing).
"""
name: "camera"
img_width: 640
img_height: 480
fov: 1.0
near: 0.01
far: 100.0
shader_pack: "rt"
skipGeneration: True # Don't generate this as a physical object
Loading
Loading