Source code for robotblockset.cameras.mujoco_camera

"""MuJoCo camera backend.

This module defines a MuJoCo-backed RGB camera wrapper that implements the shared camera interface.
It provides image capture from MuJoCo scene cameras, configurable resolution and frame-rate settings,
and optional intrinsics handling for simulation-based perception workflows. The implementation enables
simulated camera streams to be used interchangeably with hardware camera backends.

Key functionalities include:
- MuJoCo scene camera integration through the ``RGBCamera`` interface.
- Configurable camera selection, resolution, and frame-rate parameters.
- RGB frame capture and retrieval in float and uint8 formats.
- Optional camera intrinsics matrix support for simulated calibration compatibility.
- Context-manager hooks for integration in resource-managed workflows.
- Standardized behavior aligned with other robotblockset camera backends.

Copyright (c) 2026 Jozef Stefan Institute

Authors: Leon Zlajpah.
"""

from __future__ import annotations

from typing import Any, Optional
import numpy as np
from robotblockset.cameras.interfaces import RGBCamera
from robotblockset.cameras.image_converter import ImageConverter
from robotblockset.rbs_typing import CameraIntrinsicsMatrixType, CameraResolutionType, NumpyFloatImageType, NumpyIntImageType


[docs] class MujocoCam(RGBCamera): """ MuJoCo camera wrapper implementing the RGB camera interface. """ # Some standard resolutions that are likely to be supported by webcams. # 16:9 RESOLUTION_1080 = (1920, 1080) RESOLUTION_720 = (1280, 720) # 4:3 RESOLUTION_960 = (1280, 960) RESOLUTION_768 = (1024, 768) RESOLUTION_480 = (640, 480)
[docs] def __init__( self, scene: Any, mujoco_camera_id: int = 0, scene_option: Optional[Any] = None, intrinsics_matrix: Optional[CameraIntrinsicsMatrixType] = None, resolution: CameraResolutionType = RESOLUTION_480, fps: int = 30, ) -> None: """ Create a MuJoCo camera wrapper. Parameters ---------- scene : Any MuJoCo scene handle. mujoco_camera_id : int, optional int, default=0 Index of the camera in the MuJoCo model. scene_option : Any, optional Optional MuJoCo scene options for rendering. intrinsics_matrix : CameraIntrinsicsMatrixType, optional Camera intrinsics matrix with shape ``(3, 3)``. resolution : CameraResolutionType, optional CameraResolutionType, default=RESOLUTION_480 Image resolution ``(width, height)`` in pixels. fps : int, optional int, default=30 Target frame rate. """ self.scene = scene self.cam_id = mujoco_camera_id self.name = scene.model.camera(mujoco_camera_id).name self.scene_option = scene_option self._resolution = resolution if intrinsics_matrix is None: self._intrinsics_matrix = np.eye(3) else: self._intrinsics_matrix = intrinsics_matrix self._fps = fps
@property def fps(self) -> int: """The frames per second of the camera.""" return self._fps @property def resolution(self) -> CameraResolutionType: """The resolution of the camera, in pixels.""" return self._resolution def __enter__(self) -> RGBCamera: """ Enter context manager. Returns ------- RGBCamera The current camera instance. """ return self def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None: """ Exit context manager. Parameters ---------- exc_type : Any Exception type raised inside the context, if any. exc_value : Any Exception instance raised inside the context, if any. traceback : Any Exception traceback, if any. Returns ------- None """ pass
[docs] def intrinsics_matrix(self) -> CameraIntrinsicsMatrixType: """ Obtain the camera intrinsics matrix. Returns ------- CameraIntrinsicsMatrixType Camera intrinsics matrix with shape ``(3, 3)``. Raises ------ RuntimeError If intrinsics were not provided. """ if self._intrinsics_matrix is None: raise RuntimeError("OpenCVVideoCapture does not have a preset intrinsics matrix. Pass it to the constructor if you know it.") return self._intrinsics_matrix
def _grab_images(self) -> None: """Capture the latest RGB image from the MuJoCo scene.""" image = self.scene.mj_capture_camera(self.cam_id, width=self.resolution[0], height=self.resolution[1], scene_option=self.scene_option) self._frame = image def _retrieve_rgb_image(self) -> NumpyFloatImageType: """Return the current RGB image as float image.""" return ImageConverter.from_numpy_int_format(self._frame).image_in_numpy_format def _retrieve_rgb_image_as_int(self) -> NumpyIntImageType: """Return the current RGB image as uint8 image.""" return self._frame