Source code for go2.modules.video.sources.realsense_source

import time
import threading
import numpy as np
import pyrealsense2 as rs
from typing import Optional
from typing_extensions import override

from ..frame_result import FrameResult
from .camera_source import CameraSource

# Basic Camera Use: https://github.com/realsenseai/librealsense/blob/master/wrappers/python/examples/opencv_viewer_example.py
# Align: https://github.com/realsenseai/librealsense/blob/master/wrappers/python/examples/align-depth2color.py
# Optimzation/Configs: https://dev.realsenseai.com/docs/tuning-depth-cameras-for-best-performance

[docs] class RealSenseDepthCameraSource(CameraSource): def __init__(self) -> None: self._width: int = 848 self._height: int = 480 self._fps: int = 30 self._latest_frames: Optional[tuple[np.ndarray, np.ndarray]] = None self._thread = None self._stop_event = threading.Event() self._initialize_pipeline() def _initialize_pipeline(self) -> None: self._pipeline = rs.pipeline() self._config = rs.config() self._config.enable_stream(rs.stream.depth, self._width, self._height, rs.format.z16, self._fps) self._config.enable_stream(rs.stream.color, self._width, self._height, rs.format.bgr8, self._fps) @override def _start(self) -> None: self._thread = threading.Thread(target=self._rs_thread, daemon=True) self._thread.start() def _rs_thread(self): self._pipeline.start(self._config) align = rs.align(rs.stream.color) while not self._stop_event.is_set(): frames = self._pipeline.wait_for_frames() aligned = align.process(frames) color_frame = aligned.get_color_frame() depth_frame = aligned.get_depth_frame() if not color_frame or not depth_frame: continue # Here, we can be more 'lazy' when copying data, and only copy when we KNOW the frame will outlive (1000ms/fps). # See ref: https://dev.realsenseai.com/docs/frame-management/ rgb = np.asanyarray(color_frame.get_data()) depth = np.asanyarray(depth_frame.get_data()) self._latest_frames = (rgb, depth) self._pipeline.stop() @override def _get_frames(self) -> FrameResult: pair, self._latest_frames = self._latest_frames, None if pair is None: return FrameResult.pending() return FrameResult.color_and_depth(color=pair[0].copy(), depth=pair[1].copy()) @override def _shutdown(self) -> None: self._stop_event.set() if self._thread: self._thread.join() self._thread = None self._latest_frames = None