Files
RealSense-D435i-G1/tests/fake_realsense.py
T
OliviaCandClaude Opus 5.5 2e80447264 test: the API on a fake 100 ms camera (parallel captures, unchanged contract)
tests/fake_realsense.py: a pipeline whose wait_for_frames renders a textured
640x480 frameset after 100 ms (no RealSense on the development PC).
tests/test_parallel_capture.py:
- 3 parallel /api/capture take < 2x one alone (medians of 5): the criterion
  declared for optimize-streams R01. On the previous code: 391 vs 128 ms.
- /api/capture keeps its fields; parallel requests share one frame and its
  bytes, frame_id still differs per response; one thread calls the pipeline.
- /api/rgb, /api/depth, /api/depth/color decode; /ws streams; close() stops
  the acquisition thread.
Skipped when pyrealsense2 is not importable, like the existing driver tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 13:09:02 +02:00

91 lines
2.6 KiB
Python

"""A fake pyrealsense2 pipeline for tests: renders one 640x480 frameset per call after a fixed latency.
There is no RealSense on the development PC. The driver only uses a few
methods of the SDK objects, and these fakes provide exactly those.
"""
import threading
import time
import numpy as np
FAKE_LATENCY_S = 0.1 # one frame every 100 ms, as the request's test asks
WIDTH, HEIGHT = 640, 480
class FakeVideoFrame:
def __init__(self, data: np.ndarray):
self._data = data
def get_data(self):
return self._data
def get_height(self) -> int:
return self._data.shape[0]
def get_width(self) -> int:
return self._data.shape[1]
def __bool__(self) -> bool:
return True
class FakeFrameset:
def __init__(self, index: int):
rng = np.random.default_rng(index)
# Textured images, so the JPEG/PNG encoders do realistic work.
self._color = FakeVideoFrame(rng.integers(0, 255, (HEIGHT, WIDTH, 3), dtype=np.uint8))
self._depth = FakeVideoFrame(rng.integers(300, 3000, (HEIGHT, WIDTH), dtype=np.uint16))
def get_color_frame(self):
return self._color
def get_depth_frame(self):
return self._depth
class FakePipeline:
"""wait_for_frames blocks FAKE_LATENCY_S and returns a new frameset; counts the calls."""
def __init__(self, latency_s: float = FAKE_LATENCY_S):
self.latency_s = latency_s
self.calls = 0
self.max_concurrent = 0
self._active = 0
self._lock = threading.Lock()
self.stopped = False
def wait_for_frames(self, timeout_ms: int = 5000):
with self._lock:
self._active += 1
self.max_concurrent = max(self.max_concurrent, self._active)
self.calls += 1
index = self.calls
try:
time.sleep(self.latency_s)
return FakeFrameset(index)
finally:
with self._lock:
self._active -= 1
def stop(self) -> None:
self.stopped = True
def open_fake_camera(camera, pipeline: FakePipeline) -> None:
"""Put a RealSenseD435 in the 'open' state on a fake pipeline (USB 3 path, no align).
Uses the driver's own start hook when it has one, so the same helper serves
the driver before and after the acquisition thread was introduced.
"""
import pyrealsense2 as rs
camera._pipeline = pipeline
camera._align = None
camera._color_format = rs.format.bgr8
camera._depth_scale = 0.001
camera._initialized = True
camera._open = True
start = getattr(camera, "_start_acquisition", None)
if start is not None:
start()